mirror of
https://github.com/ivuorinen/nvm-auto-use.fish.git
synced 2026-02-10 03:48:46 +00:00
feat: refactor plugin architecture, enhance linting, CI & tooling
- Major refactor of core Fish functions for modularity, caching, and error handling - Improved `.editorconfig` and Makefile for stricter formatting and linting standards - Expanded linting support: added EditorConfig checks, auto-install for missing tools, and Makefile targets - Enhanced CI workflow with clearer permissions and job steps in GitHub Actions - Updated documentation in `README.md` and `CLAUDE.md` to reflect new features, advanced developer tools, and contribution guidelines - Improved Node.js version manager detection, switching, and installation logic - Added/updated utility functions for configuration, silent mode, notifications, and version extraction - Various bug fixes, code quality improvements, and expanded test coverage
This commit is contained in:
106
functions/nvm_async.fish
Normal file
106
functions/nvm_async.fish
Normal file
@@ -0,0 +1,106 @@
|
||||
function nvm_async -d "Async operations for non-blocking version management"
|
||||
set -l operation $argv[1]
|
||||
switch $operation
|
||||
case version_check
|
||||
_nvm_async_version_check $argv[2]
|
||||
case manager_check
|
||||
_nvm_async_manager_check $argv[2]
|
||||
case cleanup
|
||||
_nvm_async_cleanup
|
||||
case wait
|
||||
_nvm_async_wait $argv[2] $argv[3]
|
||||
case '*'
|
||||
echo "Usage: nvm_async [version_check|manager_check|cleanup|wait] [args...]"
|
||||
return 1
|
||||
end
|
||||
end
|
||||
|
||||
function _nvm_async_version_check -d "Async version check operation"
|
||||
set -l version_file $argv[1]
|
||||
set -l cache_key (_nvm_cache_key "$version_file")
|
||||
|
||||
# Try cache first
|
||||
if set -l cached_result (nvm_cache get "$cache_key" 60)
|
||||
echo "$cached_result"
|
||||
return 0
|
||||
end
|
||||
|
||||
# Background job for version extraction
|
||||
fish -c "
|
||||
set result (nvm_extract_version '$version_file' 2>/dev/null)
|
||||
if test -n \"\$result\"
|
||||
nvm_cache set '$cache_key' \"\$result\"
|
||||
echo \"\$result\"
|
||||
end
|
||||
" &
|
||||
|
||||
# Return job ID for potential cleanup
|
||||
jobs -l | tail -n 1 | grep -o '[0-9]*'
|
||||
end
|
||||
|
||||
function _nvm_async_manager_check -d "Async manager availability check"
|
||||
set -l manager $argv[1]
|
||||
set -l cache_key (_nvm_cache_manager_key "$manager")
|
||||
|
||||
# Try cache first (longer TTL for manager availability)
|
||||
if set -l cached_result (nvm_cache get "$cache_key" 3600)
|
||||
echo "$cached_result"
|
||||
return 0
|
||||
end
|
||||
|
||||
# Background check
|
||||
fish -c "
|
||||
if command -q '$manager'
|
||||
nvm_cache set '$cache_key' 'available'
|
||||
echo 'available'
|
||||
else
|
||||
nvm_cache set '$cache_key' 'unavailable'
|
||||
echo 'unavailable'
|
||||
end
|
||||
" &
|
||||
|
||||
jobs -l | tail -n 1 | grep -o '[0-9]*'
|
||||
end
|
||||
|
||||
function _nvm_async_cleanup -d "Clean up completed background jobs"
|
||||
for job in (jobs -p)
|
||||
if not kill -0 $job 2>/dev/null
|
||||
jobs -p | grep -v $job
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function _nvm_async_wait -d "Wait for async job with timeout"
|
||||
set -l job_id $argv[1]
|
||||
set -l timeout $argv[2]
|
||||
|
||||
if test -z "$timeout"
|
||||
set timeout 2
|
||||
end
|
||||
|
||||
# Wait for job with timeout
|
||||
set -l count 0
|
||||
while test $count -lt (math "$timeout * 10")
|
||||
if not jobs -p | grep -q "^$job_id\$"
|
||||
return 0
|
||||
end
|
||||
sleep 0.1
|
||||
set count (math "$count + 1")
|
||||
end
|
||||
|
||||
# Timeout reached, kill job
|
||||
kill -9 $job_id 2>/dev/null
|
||||
return 1
|
||||
end
|
||||
|
||||
function _nvm_async_safe_read -d "Safely read async operation result"
|
||||
set -l cache_key $argv[1]
|
||||
set -l fallback $argv[2]
|
||||
|
||||
set -l result (nvm_cache get "$cache_key")
|
||||
if test -n "$result"
|
||||
echo "$result"
|
||||
else if test -n "$fallback"
|
||||
echo "$fallback"
|
||||
end
|
||||
end
|
||||
@@ -1,130 +1,155 @@
|
||||
function nvm_auto_use --on-variable PWD
|
||||
# Detect available Node.js version manager
|
||||
set -l available_managers (nvm_compat_detect 2>/dev/null | tail -n 1)
|
||||
if test -z "$available_managers"
|
||||
# Select the Node.js version manager
|
||||
set -l manager (_nvm_auto_use_select_manager)
|
||||
if test -z "$manager"
|
||||
return
|
||||
end
|
||||
|
||||
# Use preferred manager or first available
|
||||
set -l manager
|
||||
if test -n "$_nvm_auto_use_preferred_manager"
|
||||
if contains "$_nvm_auto_use_preferred_manager" $available_managers
|
||||
set manager "$_nvm_auto_use_preferred_manager"
|
||||
end
|
||||
# Debounce rapid directory changes
|
||||
if _nvm_auto_use_should_debounce
|
||||
return
|
||||
end
|
||||
|
||||
if test -z "$manager"
|
||||
set manager $available_managers[1]
|
||||
# Check for excluded directories
|
||||
if _nvm_auto_use_is_excluded_dir
|
||||
return
|
||||
end
|
||||
|
||||
# Check if project detection is enabled and we're in a Node.js project
|
||||
# Project-only mode: only activate in Node.js projects
|
||||
if set -q _nvm_auto_use_project_only
|
||||
if not nvm_project_detect
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
# Export NODE_VERSION environment variable
|
||||
# Export NODE_VERSION environment variable if available
|
||||
if command -q node
|
||||
set -gx NODE_VERSION (node -v 2>/dev/null | string replace 'v' '')
|
||||
end
|
||||
|
||||
# Check for excluded directories
|
||||
set -l current_dir (pwd)
|
||||
for pattern in $_nvm_auto_use_excluded_dirs node_modules .git
|
||||
if string match -q "*/$pattern" "$current_dir"; or string match -q "*/$pattern/*" "$current_dir"
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
# Debouncing: prevent rapid switching
|
||||
set -l debounce_ms (_nvm_auto_use_get_debounce)
|
||||
set -l current_time (date +%s%3N 2>/dev/null; or date +%s)
|
||||
if test -n "$_nvm_auto_use_last_change"
|
||||
set -l time_diff (math "$current_time - $_nvm_auto_use_last_change")
|
||||
if test $time_diff -lt $debounce_ms
|
||||
return
|
||||
end
|
||||
end
|
||||
set -g _nvm_auto_use_last_change $current_time
|
||||
|
||||
# Find version file and its mtime
|
||||
set -l nvmrc_file (nvm_find_nvmrc)
|
||||
set -l nvmrc_mtime (_nvm_auto_use_get_mtime "$nvmrc_file")
|
||||
|
||||
# Cache check: if same file and version, skip processing
|
||||
if test "$nvmrc_file" = "$_nvm_auto_use_cached_file"
|
||||
# Skip if cache is valid
|
||||
if _nvm_auto_use_is_cache_valid "$nvmrc_file" "$nvmrc_mtime"
|
||||
return
|
||||
end
|
||||
|
||||
if test -n "$nvmrc_file"
|
||||
set -l node_version (nvm_extract_version "$nvmrc_file")
|
||||
|
||||
# Cache the file path
|
||||
set -g _nvm_auto_use_cached_file "$nvmrc_file"
|
||||
|
||||
# Validate node version format (basic semver or major version)
|
||||
if not string match -qr '^v?[0-9]+(\..*)?$' "$node_version"
|
||||
if not set -q _nvm_auto_use_silent
|
||||
echo "Invalid Node.js version format in $nvmrc_file: $node_version" >&2
|
||||
end
|
||||
return 1
|
||||
end
|
||||
|
||||
# Remove 'v' prefix if present
|
||||
set node_version (string replace -r '^v' '' "$node_version")
|
||||
|
||||
# Cache the version
|
||||
set -g _nvm_auto_use_cached_version "$node_version"
|
||||
|
||||
# Check the current version
|
||||
set -l current_version
|
||||
if command -q node
|
||||
set current_version (node -v 2>/dev/null | sed 's/v//')
|
||||
end
|
||||
|
||||
if test "$node_version" != "$current_version"
|
||||
if not set -q _nvm_auto_use_silent
|
||||
echo "Switching to Node.js v$node_version"
|
||||
end
|
||||
|
||||
# Send notification if enabled
|
||||
if not set -q _nvm_auto_use_silent
|
||||
nvm_notify "Switched to Node.js v$node_version"
|
||||
end
|
||||
|
||||
if not nvm_compat_use $manager $node_version 2>/dev/null
|
||||
# Check if auto-install is disabled
|
||||
if set -q _nvm_auto_use_no_install
|
||||
if not set -q _nvm_auto_use_silent
|
||||
echo "Node.js version $node_version not found (auto-install disabled)" >&2
|
||||
end
|
||||
return 1
|
||||
end
|
||||
|
||||
if not set -q _nvm_auto_use_silent
|
||||
echo "Node.js version $node_version not found, installing..."
|
||||
end
|
||||
if nvm_compat_install $manager $node_version >/dev/null 2>&1
|
||||
nvm_compat_use $manager $node_version >/dev/null 2>&1
|
||||
if not set -q _nvm_auto_use_silent
|
||||
echo "Installed and switched to Node.js v$node_version"
|
||||
end
|
||||
else
|
||||
if not set -q _nvm_auto_use_silent
|
||||
echo "Failed to install Node.js version $node_version" >&2
|
||||
end
|
||||
return 1
|
||||
end
|
||||
end
|
||||
|
||||
# Update cached version after successful switch
|
||||
set -g _nvm_auto_use_cached_version "$node_version"
|
||||
|
||||
# Update NODE_VERSION environment variable
|
||||
set -gx NODE_VERSION "$node_version"
|
||||
end
|
||||
_nvm_auto_use_switch_version "$manager" "$nvmrc_file" "$nvmrc_mtime"
|
||||
else
|
||||
# Clear cache if no .nvmrc found
|
||||
set -e _nvm_auto_use_cached_file
|
||||
set -e _nvm_auto_use_cached_version
|
||||
_nvm_auto_use_clear_cache
|
||||
end
|
||||
end
|
||||
|
||||
function _nvm_auto_use_select_manager
|
||||
set -l available_managers (nvm_compat_detect 2>/dev/null)
|
||||
if test -z "$available_managers"
|
||||
return
|
||||
end
|
||||
if test -n "$_nvm_auto_use_preferred_manager"
|
||||
if contains "$_nvm_auto_use_preferred_manager" $available_managers
|
||||
echo "$_nvm_auto_use_preferred_manager"
|
||||
return
|
||||
end
|
||||
end
|
||||
echo $available_managers[1]
|
||||
end
|
||||
|
||||
function _nvm_auto_use_should_debounce
|
||||
set -l debounce_ms (_nvm_auto_use_get_debounce)
|
||||
set -l current_time (date +%s%3N 2>/dev/null; or math "(date +%s) * 1000")
|
||||
if test -n "$_nvm_auto_use_last_change"
|
||||
set -l time_diff (math "$current_time - $_nvm_auto_use_last_change")
|
||||
if test $time_diff -lt $debounce_ms
|
||||
return 0
|
||||
end
|
||||
end
|
||||
set -g _nvm_auto_use_last_change $current_time
|
||||
return 1
|
||||
end
|
||||
|
||||
function _nvm_auto_use_is_excluded_dir
|
||||
set -l current_dir (pwd)
|
||||
set -l patterns $_nvm_auto_use_excluded_dirs node_modules .git
|
||||
for pattern in $patterns
|
||||
if string match -q "*/$pattern" "$current_dir"; or string match -q "*/$pattern/*" "$current_dir"
|
||||
return 0
|
||||
end
|
||||
end
|
||||
return 1
|
||||
end
|
||||
|
||||
function _nvm_auto_use_get_mtime
|
||||
set -l file $argv[1]
|
||||
if test -n "$file"
|
||||
stat -c %Y "$file" 2>/dev/null; or stat -f %m "$file" 2>/dev/null
|
||||
end
|
||||
end
|
||||
|
||||
function _nvm_auto_use_is_cache_valid
|
||||
set -l file $argv[1]
|
||||
set -l mtime $argv[2]
|
||||
if test "$file" = "$_nvm_auto_use_cached_file"; and test "$mtime" = "$_nvm_auto_use_cached_mtime"
|
||||
return 0
|
||||
end
|
||||
return 1
|
||||
end
|
||||
|
||||
function _nvm_auto_use_switch_version
|
||||
set -l manager $argv[1]
|
||||
set -l nvmrc_file $argv[2]
|
||||
set -l nvmrc_mtime $argv[3]
|
||||
set -l node_version (nvm_extract_version "$nvmrc_file")
|
||||
set -g _nvm_auto_use_cached_file "$nvmrc_file"
|
||||
set -g _nvm_auto_use_cached_mtime "$nvmrc_mtime"
|
||||
if not string match -qr '^v?[0-9]+(\..*)?$' "$node_version"
|
||||
if not set -q _nvm_auto_use_silent
|
||||
echo "Invalid Node.js version format in $nvmrc_file: $node_version" >&2
|
||||
end
|
||||
return 1
|
||||
end
|
||||
set node_version (string replace -r '^v' '' "$node_version")
|
||||
set -g _nvm_auto_use_cached_version "$node_version"
|
||||
set -l current_version
|
||||
if command -q node
|
||||
set current_version (node -v 2>/dev/null | sed 's/v//')
|
||||
end
|
||||
if test "$node_version" != "$current_version"
|
||||
if not set -q _nvm_auto_use_silent
|
||||
echo "Switching to Node.js v$node_version"
|
||||
nvm_notify "Switched to Node.js v$node_version"
|
||||
end
|
||||
if not nvm_compat_use $manager $node_version 2>/dev/null
|
||||
if set -q _nvm_auto_use_no_install
|
||||
if not set -q _nvm_auto_use_silent
|
||||
echo "Node.js version $node_version not found (auto-install disabled)" >&2
|
||||
end
|
||||
return 1
|
||||
end
|
||||
if not set -q _nvm_auto_use_silent
|
||||
echo "Node.js version $node_version not found, installing..."
|
||||
end
|
||||
if nvm_compat_install $manager $node_version >/dev/null 2>&1
|
||||
nvm_compat_use $manager $node_version >/dev/null 2>&1
|
||||
if not set -q _nvm_auto_use_silent
|
||||
echo "Installed and switched to Node.js v$node_version"
|
||||
end
|
||||
else
|
||||
if not set -q _nvm_auto_use_silent
|
||||
echo "Failed to install Node.js version $node_version" >&2
|
||||
end
|
||||
return 1
|
||||
end
|
||||
end
|
||||
set -g _nvm_auto_use_cached_version "$node_version"
|
||||
set -gx NODE_VERSION "$node_version"
|
||||
end
|
||||
end
|
||||
|
||||
function _nvm_auto_use_clear_cache
|
||||
set -e _nvm_auto_use_cached_file
|
||||
set -e _nvm_auto_use_cached_version
|
||||
set -e _nvm_auto_use_cached_mtime
|
||||
end
|
||||
|
||||
@@ -1,88 +1,126 @@
|
||||
function nvm_auto_use_config -d "Configure nvm-auto-use settings"
|
||||
if test (count $argv) -eq 0
|
||||
echo "nvm-auto-use configuration:"
|
||||
echo " auto_install: "(test -n "$_nvm_auto_use_no_install"; and echo "disabled"; or echo "enabled")
|
||||
echo " silent: "(test -n "$_nvm_auto_use_silent"; and echo "enabled"; or echo "disabled")
|
||||
echo " debounce_ms: "(_nvm_auto_use_get_debounce)
|
||||
echo " excluded_dirs: "(_nvm_auto_use_get_excluded_dirs)
|
||||
echo " preferred_manager: "(test -n "$_nvm_auto_use_preferred_manager"; and echo "$_nvm_auto_use_preferred_manager"; or echo "auto-detect")
|
||||
_nvm_auto_use_config_show
|
||||
return
|
||||
end
|
||||
|
||||
switch $argv[1]
|
||||
case auto_install
|
||||
switch $argv[2]
|
||||
case on enable true 1
|
||||
set -e _nvm_auto_use_no_install
|
||||
echo "Auto-install enabled"
|
||||
case off disable false 0
|
||||
set -g _nvm_auto_use_no_install 1
|
||||
echo "Auto-install disabled"
|
||||
case '*'
|
||||
echo "Usage: nvm_auto_use_config auto_install [on|off]"
|
||||
end
|
||||
_nvm_auto_use_config_auto_install $argv[2]
|
||||
case silent
|
||||
switch $argv[2]
|
||||
case on enable true 1
|
||||
set -g _nvm_auto_use_silent 1
|
||||
echo "Silent mode enabled"
|
||||
case off disable false 0
|
||||
set -e _nvm_auto_use_silent
|
||||
echo "Silent mode disabled"
|
||||
case '*'
|
||||
echo "Usage: nvm_auto_use_config silent [on|off]"
|
||||
end
|
||||
_nvm_auto_use_config_silent $argv[2]
|
||||
case debounce
|
||||
if test -n "$argv[2]" -a (string match -r '^[0-9]+$' "$argv[2]")
|
||||
set -g _nvm_auto_use_debounce_ms $argv[2]
|
||||
echo "Debounce set to $argv[2]ms"
|
||||
else
|
||||
echo "Usage: nvm_auto_use_config debounce <milliseconds>"
|
||||
end
|
||||
_nvm_auto_use_config_debounce $argv[2]
|
||||
case exclude
|
||||
if test -n "$argv[2]"
|
||||
set -g _nvm_auto_use_excluded_dirs $_nvm_auto_use_excluded_dirs $argv[2]
|
||||
echo "Added $argv[2] to excluded directories"
|
||||
else
|
||||
echo "Usage: nvm_auto_use_config exclude <directory_pattern>"
|
||||
end
|
||||
_nvm_auto_use_config_exclude $argv[2]
|
||||
case include
|
||||
if test -n "$argv[2]"
|
||||
set -l index (contains -i "$argv[2]" $_nvm_auto_use_excluded_dirs)
|
||||
if test -n "$index"
|
||||
set -e _nvm_auto_use_excluded_dirs[$index]
|
||||
echo "Removed $argv[2] from excluded directories"
|
||||
else
|
||||
echo "$argv[2] was not in excluded directories"
|
||||
end
|
||||
else
|
||||
echo "Usage: nvm_auto_use_config include <directory_pattern>"
|
||||
end
|
||||
_nvm_auto_use_config_include $argv[2]
|
||||
case manager
|
||||
if test -n "$argv[2]"
|
||||
if contains "$argv[2]" nvm fnm volta asdf
|
||||
set -g _nvm_auto_use_preferred_manager "$argv[2]"
|
||||
echo "Preferred manager set to $argv[2]"
|
||||
else
|
||||
echo "Unsupported manager. Supported: nvm, fnm, volta, asdf"
|
||||
end
|
||||
else
|
||||
set -e _nvm_auto_use_preferred_manager
|
||||
echo "Reset to auto-detect manager"
|
||||
end
|
||||
_nvm_auto_use_config_manager $argv[2]
|
||||
case reset
|
||||
set -e _nvm_auto_use_no_install
|
||||
set -e _nvm_auto_use_silent
|
||||
set -e _nvm_auto_use_debounce_ms
|
||||
set -e _nvm_auto_use_excluded_dirs
|
||||
set -e _nvm_auto_use_preferred_manager
|
||||
echo "Configuration reset to defaults"
|
||||
_nvm_auto_use_config_reset
|
||||
case '*'
|
||||
echo "Usage: nvm_auto_use_config [auto_install|silent|debounce|exclude|include|manager|reset] [value]"
|
||||
return 1
|
||||
end
|
||||
end
|
||||
|
||||
function _nvm_auto_use_config_show
|
||||
echo "nvm-auto-use configuration:"
|
||||
echo " auto_install: "(test -n "$_nvm_auto_use_no_install"; and echo "disabled"; or echo "enabled")
|
||||
echo " silent: "(test -n "$_nvm_auto_use_silent"; and echo "enabled"; or echo "disabled")
|
||||
echo " debounce_ms: "(_nvm_auto_use_get_debounce)
|
||||
echo " excluded_dirs: "(_nvm_auto_use_get_excluded_dirs)
|
||||
echo " preferred_manager: "(test -n "$_nvm_auto_use_preferred_manager"; and echo "$_nvm_auto_use_preferred_manager"; or echo "auto-detect")
|
||||
end
|
||||
|
||||
function _nvm_auto_use_config_auto_install
|
||||
set -l value $argv[1]
|
||||
switch $value
|
||||
case on enable true 1
|
||||
set -e _nvm_auto_use_no_install
|
||||
echo "Auto-install enabled"
|
||||
case off disable false 0
|
||||
set -g _nvm_auto_use_no_install 1
|
||||
echo "Auto-install disabled"
|
||||
case '*'
|
||||
echo "Usage: nvm_auto_use_config auto_install [on|off]"
|
||||
end
|
||||
end
|
||||
|
||||
function _nvm_auto_use_config_silent
|
||||
set -l value $argv[1]
|
||||
switch $value
|
||||
case on enable true 1
|
||||
set -g _nvm_auto_use_silent 1
|
||||
echo "Silent mode enabled"
|
||||
case off disable false 0
|
||||
set -e _nvm_auto_use_silent
|
||||
echo "Silent mode disabled"
|
||||
case '*'
|
||||
echo "Usage: nvm_auto_use_config silent [on|off]"
|
||||
end
|
||||
end
|
||||
|
||||
function _nvm_auto_use_config_debounce
|
||||
set -l value $argv[1]
|
||||
if test -n "$value" -a (string match -r '^[0-9]+$' "$value")
|
||||
set -g _nvm_auto_use_debounce_ms $value
|
||||
echo "Debounce set to $value ms"
|
||||
else
|
||||
echo "Usage: nvm_auto_use_config debounce <milliseconds>"
|
||||
end
|
||||
end
|
||||
|
||||
function _nvm_auto_use_config_exclude
|
||||
set -l value $argv[1]
|
||||
if test -n "$value"
|
||||
set -g _nvm_auto_use_excluded_dirs $_nvm_auto_use_excluded_dirs $value
|
||||
echo "Added $value to excluded directories"
|
||||
else
|
||||
echo "Usage: nvm_auto_use_config exclude <directory_pattern>"
|
||||
end
|
||||
end
|
||||
|
||||
function _nvm_auto_use_config_include
|
||||
set -l value $argv[1]
|
||||
if test -n "$value"
|
||||
set -l index (contains -i "$value" $_nvm_auto_use_excluded_dirs)
|
||||
if test -n "$index"
|
||||
set -e _nvm_auto_use_excluded_dirs[$index]
|
||||
echo "Removed $value from excluded directories"
|
||||
else
|
||||
echo "$value was not in excluded directories"
|
||||
end
|
||||
else
|
||||
echo "Usage: nvm_auto_use_config include <directory_pattern>"
|
||||
end
|
||||
end
|
||||
|
||||
function _nvm_auto_use_config_manager
|
||||
set -l value $argv[1]
|
||||
if test -n "$value"
|
||||
if contains "$value" nvm fnm volta asdf
|
||||
set -g _nvm_auto_use_preferred_manager "$value"
|
||||
echo "Preferred manager set to $value"
|
||||
else
|
||||
echo "Unsupported manager. Supported: nvm, fnm, volta, asdf"
|
||||
end
|
||||
else
|
||||
set -e _nvm_auto_use_preferred_manager
|
||||
echo "Reset to auto-detect manager"
|
||||
end
|
||||
end
|
||||
|
||||
function _nvm_auto_use_config_reset
|
||||
set -e _nvm_auto_use_no_install
|
||||
set -e _nvm_auto_use_silent
|
||||
set -e _nvm_auto_use_debounce_ms
|
||||
set -e _nvm_auto_use_excluded_dirs
|
||||
set -e _nvm_auto_use_preferred_manager
|
||||
echo "Configuration reset to defaults"
|
||||
end
|
||||
|
||||
function _nvm_auto_use_get_debounce
|
||||
if test -n "$_nvm_auto_use_debounce_ms"
|
||||
echo "$_nvm_auto_use_debounce_ms"
|
||||
|
||||
@@ -13,7 +13,7 @@ function nvm_auto_use_silent -d "Enable or disable silent mode for nvm-auto-use"
|
||||
set -g _nvm_auto_use_silent 1
|
||||
echo "Silent mode enabled"
|
||||
case off disable false 0
|
||||
set -e _nvm_auto_use_silent
|
||||
set -e -g _nvm_auto_use_silent
|
||||
echo "Silent mode disabled"
|
||||
case '*'
|
||||
echo "Usage: nvm_auto_use_silent [on|off]"
|
||||
|
||||
110
functions/nvm_cache.fish
Normal file
110
functions/nvm_cache.fish
Normal file
@@ -0,0 +1,110 @@
|
||||
function nvm_cache -d "XDG-compliant cache management with TTL"
|
||||
set -l action $argv[1]
|
||||
set -l key $argv[2]
|
||||
set -l value $argv[3]
|
||||
set -l ttl $argv[4]
|
||||
|
||||
switch $action
|
||||
case get
|
||||
_nvm_cache_get "$key" "$ttl"
|
||||
case set
|
||||
_nvm_cache_set "$key" "$value"
|
||||
case delete
|
||||
_nvm_cache_delete "$key"
|
||||
case clear
|
||||
_nvm_cache_clear
|
||||
case stats
|
||||
_nvm_cache_stats
|
||||
case '*'
|
||||
echo "Usage: nvm_cache [get|set|delete|clear|stats] <key> [value] [ttl]"
|
||||
return 1
|
||||
end
|
||||
end
|
||||
|
||||
function _nvm_cache_dir -d "Get XDG cache directory for nvm-auto-use"
|
||||
if set -q XDG_CACHE_HOME
|
||||
echo "$XDG_CACHE_HOME/nvm-auto-use"
|
||||
else
|
||||
echo "$HOME/.cache/nvm-auto-use"
|
||||
end
|
||||
end
|
||||
|
||||
function _nvm_cache_get -d "Get cache value by key, respecting TTL"
|
||||
set -l key $argv[1]
|
||||
set -l ttl $argv[2]
|
||||
set -l cache_dir (_nvm_cache_dir)
|
||||
set -l cache_file "$cache_dir/$key"
|
||||
|
||||
if not test -f "$cache_file"
|
||||
return 1
|
||||
end
|
||||
|
||||
# Check TTL
|
||||
set -l cache_time (stat -c %Y "$cache_file" 2>/dev/null; or stat -f %m "$cache_file" 2>/dev/null)
|
||||
set -l current_time (date +%s)
|
||||
set -l default_ttl 300 # 5 minutes default
|
||||
|
||||
if test -n "$ttl"
|
||||
set default_ttl $ttl
|
||||
end
|
||||
|
||||
if test (math "$current_time - $cache_time") -gt $default_ttl
|
||||
rm "$cache_file" 2>/dev/null
|
||||
return 1
|
||||
end
|
||||
|
||||
cat "$cache_file"
|
||||
return 0
|
||||
end
|
||||
|
||||
function _nvm_cache_set -d "Set cache value by key"
|
||||
set -l key $argv[1]
|
||||
set -l value $argv[2]
|
||||
set -l cache_dir (_nvm_cache_dir)
|
||||
set -l cache_file "$cache_dir/$key"
|
||||
|
||||
if test -z "$value"
|
||||
return 1
|
||||
end
|
||||
|
||||
mkdir -p "$cache_dir" 2>/dev/null
|
||||
echo "$value" >"$cache_file" 2>/dev/null
|
||||
return $status
|
||||
end
|
||||
|
||||
function _nvm_cache_delete -d "Delete cache value by key"
|
||||
set -l key $argv[1]
|
||||
set -l cache_dir (_nvm_cache_dir)
|
||||
set -l cache_file "$cache_dir/$key"
|
||||
rm "$cache_file" 2>/dev/null
|
||||
return 0
|
||||
end
|
||||
|
||||
function _nvm_cache_clear -d "Clear all cache files"
|
||||
set -l cache_dir (_nvm_cache_dir)
|
||||
rm -rf "$cache_dir" 2>/dev/null
|
||||
return 0
|
||||
end
|
||||
|
||||
function _nvm_cache_stats -d "Show cache statistics"
|
||||
set -l cache_dir (_nvm_cache_dir)
|
||||
if test -d "$cache_dir"
|
||||
echo "Cache directory: $cache_dir"
|
||||
echo "Cache files: "(find "$cache_dir" -type f 2>/dev/null | wc -l)
|
||||
echo "Cache size: "(du -sh "$cache_dir" 2>/dev/null | cut -f1)
|
||||
else
|
||||
echo "No cache directory found"
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
function _nvm_cache_key -d "Generate cache key from directory and file"
|
||||
set -l dir (pwd)
|
||||
set -l file_hash (echo "$argv[1]" | shasum | cut -d' ' -f1)
|
||||
echo "dir_$(echo "$dir" | shasum | cut -d' ' -f1)_$file_hash"
|
||||
end
|
||||
|
||||
function _nvm_cache_manager_key -d "Generate cache key for manager availability"
|
||||
set -l manager $argv[1]
|
||||
echo "manager_$manager"
|
||||
end
|
||||
@@ -36,13 +36,13 @@ function nvm_compat_use -a manager version -d "Use specified version with detect
|
||||
|
||||
switch $manager
|
||||
case nvm
|
||||
nvm use $version
|
||||
nvm use $version; or return $status
|
||||
case fnm
|
||||
fnm use $version
|
||||
fnm use $version; or return $status
|
||||
case volta
|
||||
volta pin node@$version
|
||||
volta pin node@$version; or return $status
|
||||
case asdf
|
||||
asdf local nodejs $version
|
||||
asdf local nodejs $version; or return $status
|
||||
case '*'
|
||||
echo "Unsupported manager: $manager"
|
||||
return 1
|
||||
@@ -57,13 +57,13 @@ function nvm_compat_install -a manager version -d "Install specified version wit
|
||||
|
||||
switch $manager
|
||||
case nvm
|
||||
nvm install $version
|
||||
nvm install $version; or return $status
|
||||
case fnm
|
||||
fnm install $version
|
||||
fnm install $version; or return $status
|
||||
case volta
|
||||
volta install node@$version
|
||||
volta install node@$version; or return $status
|
||||
case asdf
|
||||
asdf install nodejs $version
|
||||
asdf install nodejs $version; or return $status
|
||||
case '*'
|
||||
echo "Unsupported manager: $manager"
|
||||
return 1
|
||||
|
||||
428
functions/nvm_doctor.fish
Normal file
428
functions/nvm_doctor.fish
Normal file
@@ -0,0 +1,428 @@
|
||||
function nvm_doctor -d "Comprehensive diagnostic and debugging tool"
|
||||
set -l action $argv[1]
|
||||
|
||||
switch $action
|
||||
case check
|
||||
_nvm_doctor_full_check
|
||||
case system
|
||||
_nvm_doctor_system_info
|
||||
case managers
|
||||
_nvm_doctor_check_managers
|
||||
case permissions
|
||||
_nvm_doctor_check_permissions
|
||||
case config
|
||||
_nvm_doctor_check_config
|
||||
case cache
|
||||
_nvm_doctor_check_cache
|
||||
case security
|
||||
_nvm_doctor_security_audit
|
||||
case performance
|
||||
_nvm_doctor_performance_check
|
||||
case fix
|
||||
_nvm_doctor_auto_fix $argv[2..-1]
|
||||
case '*'
|
||||
echo "Usage: nvm_doctor [check|system|managers|permissions|config|cache|security|performance|fix] [args...]"
|
||||
echo
|
||||
echo "Commands:"
|
||||
echo " check - Run comprehensive diagnostic check"
|
||||
echo " system - Show system information"
|
||||
echo " managers - Check version manager status"
|
||||
echo " permissions - Check file and directory permissions"
|
||||
echo " config - Validate configuration"
|
||||
echo " cache - Check cache status and health"
|
||||
echo " security - Run security audit"
|
||||
echo " performance - Analyze performance issues"
|
||||
echo " fix - Attempt to fix common issues"
|
||||
return 1
|
||||
end
|
||||
end
|
||||
|
||||
function _nvm_doctor_full_check -d "Run comprehensive diagnostic check"
|
||||
echo "🩺 NVM Auto-Use Doctor - Comprehensive Check"
|
||||
echo "============================================="
|
||||
echo
|
||||
|
||||
set -l issues 0
|
||||
|
||||
# System check
|
||||
echo "🖥️ System Information"
|
||||
echo ---------------------
|
||||
_nvm_doctor_system_info
|
||||
echo
|
||||
|
||||
# Manager check
|
||||
echo "🔧 Version Manager Status"
|
||||
echo -------------------------
|
||||
_nvm_doctor_check_managers
|
||||
set issues (math "$issues + $status")
|
||||
echo
|
||||
|
||||
# Configuration check
|
||||
echo "⚙️ Configuration Status"
|
||||
echo ------------------------
|
||||
_nvm_doctor_check_config
|
||||
set issues (math "$issues + $status")
|
||||
echo
|
||||
|
||||
# Permissions check
|
||||
echo "🔐 Permissions Check"
|
||||
echo -------------------
|
||||
_nvm_doctor_check_permissions
|
||||
set issues (math "$issues + $status")
|
||||
echo
|
||||
|
||||
# Cache check
|
||||
echo "🗄️ Cache Status"
|
||||
echo ----------------
|
||||
_nvm_doctor_check_cache
|
||||
set issues (math "$issues + $status")
|
||||
echo
|
||||
|
||||
# Security audit
|
||||
echo "🔒 Security Audit"
|
||||
echo -----------------
|
||||
_nvm_doctor_security_audit
|
||||
set issues (math "$issues + $status")
|
||||
echo
|
||||
|
||||
# Performance check
|
||||
echo "⚡ Performance Analysis"
|
||||
echo ----------------------
|
||||
_nvm_doctor_performance_check
|
||||
set issues (math "$issues + $status")
|
||||
echo
|
||||
|
||||
# Summary
|
||||
echo "📋 Diagnostic Summary"
|
||||
echo "====================="
|
||||
if test $issues -eq 0
|
||||
echo "✅ All checks passed! Your nvm-auto-use setup is healthy."
|
||||
else
|
||||
echo "⚠️ Found $issues issue(s) that may need attention."
|
||||
echo "💡 Run 'nvm_doctor fix' to attempt automatic fixes."
|
||||
end
|
||||
|
||||
return $issues
|
||||
end
|
||||
|
||||
function _nvm_doctor_system_info -d "Display system information"
|
||||
echo "OS: "(uname -s)" "(uname -r)
|
||||
echo "Architecture: "(uname -m)
|
||||
echo "Shell: $SHELL"
|
||||
echo "Fish version: "(fish --version)
|
||||
|
||||
if command -q node
|
||||
echo "Node.js: "(node --version)
|
||||
else
|
||||
echo "Node.js: Not installed"
|
||||
end
|
||||
|
||||
if command -q npm
|
||||
echo "npm: "(npm --version)
|
||||
else
|
||||
echo "npm: Not available"
|
||||
end
|
||||
|
||||
echo "PATH entries: "(echo $PATH | string split ':' | wc -l)
|
||||
echo "Current directory: "(pwd)
|
||||
end
|
||||
|
||||
function _nvm_doctor_check_managers -d "Check version manager availability and status"
|
||||
set -l issues 0
|
||||
set -l managers (nvm_compat_detect 2>/dev/null)
|
||||
|
||||
if test -z "$managers"
|
||||
echo "❌ No Node.js version managers found"
|
||||
echo " Install at least one: nvm, fnm, volta, or asdf"
|
||||
set issues (math "$issues + 1")
|
||||
else
|
||||
echo "✅ Found managers: $managers"
|
||||
|
||||
# Check each manager's status
|
||||
for manager in (echo $managers | string split ' ')
|
||||
echo " 📋 $manager status:"
|
||||
switch $manager
|
||||
case nvm
|
||||
if test -f "$HOME/.nvm/nvm.sh"
|
||||
echo " ✅ NVM script found"
|
||||
if command -q nvm
|
||||
echo " ✅ NVM command available"
|
||||
else
|
||||
echo " ⚠️ NVM not in PATH (normal for Fish)"
|
||||
end
|
||||
else
|
||||
echo " ❌ NVM installation not found"
|
||||
set issues (math "$issues + 1")
|
||||
end
|
||||
case fnm
|
||||
if command -q fnm
|
||||
echo " ✅ FNM available: "(fnm --version)
|
||||
else
|
||||
echo " ❌ FNM not found in PATH"
|
||||
set issues (math "$issues + 1")
|
||||
end
|
||||
case volta
|
||||
if command -q volta
|
||||
echo " ✅ Volta available: "(volta --version)
|
||||
else
|
||||
echo " ❌ Volta not found in PATH"
|
||||
set issues (math "$issues + 1")
|
||||
end
|
||||
case asdf
|
||||
if command -q asdf
|
||||
echo " ✅ asdf available: "(asdf --version)
|
||||
if asdf plugin list | grep -q nodejs
|
||||
echo " ✅ nodejs plugin installed"
|
||||
else
|
||||
echo " ❌ nodejs plugin not installed"
|
||||
set issues (math "$issues + 1")
|
||||
end
|
||||
else
|
||||
echo " ❌ asdf not found in PATH"
|
||||
set issues (math "$issues + 1")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return $issues
|
||||
end
|
||||
|
||||
function _nvm_doctor_check_permissions -d "Check file and directory permissions"
|
||||
set -l issues 0
|
||||
|
||||
# Check Fish functions directory
|
||||
set -l functions_dir (dirname (status current-filename))
|
||||
if test -d "$functions_dir"
|
||||
echo "✅ Functions directory accessible: $functions_dir"
|
||||
|
||||
# Check individual function files
|
||||
for func_file in "$functions_dir"/nvm_*.fish
|
||||
if test -r "$func_file"
|
||||
echo " ✅ $(basename $func_file) readable"
|
||||
else
|
||||
echo " ❌ $(basename $func_file) not readable"
|
||||
set issues (math "$issues + 1")
|
||||
end
|
||||
end
|
||||
else
|
||||
echo "❌ Functions directory not found"
|
||||
set issues (math "$issues + 1")
|
||||
end
|
||||
|
||||
# Check cache directory permissions
|
||||
set -l cache_dir
|
||||
if set -q XDG_CACHE_HOME
|
||||
set cache_dir "$XDG_CACHE_HOME/nvm-auto-use"
|
||||
else
|
||||
set cache_dir "$HOME/.cache/nvm-auto-use"
|
||||
end
|
||||
|
||||
if test -d "$cache_dir"
|
||||
if test -w "$cache_dir"
|
||||
echo "✅ Cache directory writable: $cache_dir"
|
||||
else
|
||||
echo "❌ Cache directory not writable: $cache_dir"
|
||||
set issues (math "$issues + 1")
|
||||
end
|
||||
else
|
||||
echo "ℹ️ Cache directory doesn't exist (will be created as needed)"
|
||||
end
|
||||
|
||||
# Check current directory permissions for version files
|
||||
if test -r "."
|
||||
echo "✅ Current directory readable"
|
||||
|
||||
for version_file in .nvmrc .node-version .tool-versions package.json
|
||||
if test -f "$version_file"
|
||||
if test -r "$version_file"
|
||||
echo " ✅ $version_file readable"
|
||||
else
|
||||
echo " ❌ $version_file not readable"
|
||||
set issues (math "$issues + 1")
|
||||
end
|
||||
end
|
||||
end
|
||||
else
|
||||
echo "❌ Current directory not readable"
|
||||
set issues (math "$issues + 1")
|
||||
end
|
||||
|
||||
return $issues
|
||||
end
|
||||
|
||||
function _nvm_doctor_check_config -d "Validate configuration"
|
||||
set -l issues 0
|
||||
|
||||
echo "Configuration variables:"
|
||||
|
||||
# Check debounce setting
|
||||
set -l debounce (_nvm_auto_use_get_debounce 2>/dev/null)
|
||||
if test -n "$debounce"
|
||||
echo " ✅ Debounce: ${debounce}ms"
|
||||
else
|
||||
echo " ℹ️ Debounce: Default (500ms)"
|
||||
end
|
||||
|
||||
# Check excluded directories
|
||||
set -l excluded (_nvm_auto_use_get_excluded_dirs 2>/dev/null)
|
||||
echo " ✅ Excluded dirs: $excluded"
|
||||
|
||||
# Check auto-install setting
|
||||
if set -q _nvm_auto_use_no_install
|
||||
echo " ✅ Auto-install: Disabled"
|
||||
else
|
||||
echo " ✅ Auto-install: Enabled"
|
||||
end
|
||||
|
||||
# Check silent mode
|
||||
if set -q _nvm_auto_use_silent
|
||||
echo " ✅ Silent mode: Enabled"
|
||||
else
|
||||
echo " ✅ Silent mode: Disabled"
|
||||
end
|
||||
|
||||
# Check preferred manager
|
||||
if set -q _nvm_auto_use_preferred_manager
|
||||
echo " ✅ Preferred manager: $_nvm_auto_use_preferred_manager"
|
||||
else
|
||||
echo " ✅ Preferred manager: Auto-detect"
|
||||
end
|
||||
|
||||
# Validate security policies
|
||||
echo "Security policies:"
|
||||
nvm_security policy list 2>/dev/null || echo " ℹ️ No security policies set"
|
||||
|
||||
return $issues
|
||||
end
|
||||
|
||||
function _nvm_doctor_check_cache -d "Check cache status and health"
|
||||
set -l issues 0
|
||||
|
||||
# Get cache stats
|
||||
nvm_cache stats
|
||||
|
||||
# Check for corrupted cache files
|
||||
set -l cache_dir
|
||||
if set -q XDG_CACHE_HOME
|
||||
set cache_dir "$XDG_CACHE_HOME/nvm-auto-use"
|
||||
else
|
||||
set cache_dir "$HOME/.cache/nvm-auto-use"
|
||||
end
|
||||
|
||||
if test -d "$cache_dir"
|
||||
set -l cache_files (find "$cache_dir" -type f 2>/dev/null)
|
||||
|
||||
for cache_file in $cache_files
|
||||
if test -s "$cache_file"
|
||||
echo " ✅ $(basename $cache_file) valid"
|
||||
else
|
||||
echo " ⚠️ $(basename $cache_file) empty (may be normal)"
|
||||
end
|
||||
end
|
||||
|
||||
# Check for very old cache files
|
||||
set -l old_files (find "$cache_dir" -type f -mtime +7 2>/dev/null)
|
||||
if test -n "$old_files"
|
||||
echo " ℹ️ Found "(echo "$old_files" | wc -l)" cache files older than 7 days"
|
||||
end
|
||||
else
|
||||
echo " ℹ️ No cache directory found"
|
||||
end
|
||||
|
||||
return $issues
|
||||
end
|
||||
|
||||
function _nvm_doctor_security_audit -d "Run security audit"
|
||||
nvm_security audit
|
||||
end
|
||||
|
||||
function _nvm_doctor_performance_check -d "Analyze performance issues"
|
||||
set -l issues 0
|
||||
|
||||
echo "Performance analysis:"
|
||||
|
||||
# Check for excessive cache files
|
||||
set -l cache_dir
|
||||
if set -q XDG_CACHE_HOME
|
||||
set cache_dir "$XDG_CACHE_HOME/nvm-auto-use"
|
||||
else
|
||||
set cache_dir "$HOME/.cache/nvm-auto-use"
|
||||
end
|
||||
|
||||
if test -d "$cache_dir"
|
||||
set -l cache_count (find "$cache_dir" -type f 2>/dev/null | wc -l)
|
||||
if test $cache_count -gt 100
|
||||
echo " ⚠️ Large number of cache files ($cache_count) - consider cleanup"
|
||||
set issues (math "$issues + 1")
|
||||
else
|
||||
echo " ✅ Reasonable cache size ($cache_count files)"
|
||||
end
|
||||
end
|
||||
|
||||
# Check for very long directory paths
|
||||
set -l current_path (pwd)
|
||||
set -l path_length (string length "$current_path")
|
||||
if test $path_length -gt 200
|
||||
echo " ⚠️ Very long current path may slow operations: $path_length characters"
|
||||
set issues (math "$issues + 1")
|
||||
else
|
||||
echo " ✅ Path length reasonable: $path_length characters"
|
||||
end
|
||||
|
||||
# Check for deep directory nesting
|
||||
set -l depth (echo "$current_path" | string replace -a '/' '\n' | wc -l)
|
||||
if test $depth -gt 15
|
||||
echo " ⚠️ Deep directory nesting may slow file searches: $depth levels"
|
||||
set issues (math "$issues + 1")
|
||||
else
|
||||
echo " ✅ Directory depth reasonable: $depth levels"
|
||||
end
|
||||
|
||||
return $issues
|
||||
end
|
||||
|
||||
function _nvm_doctor_auto_fix -d "Attempt to fix common issues"
|
||||
set -l fix_type $argv[1]
|
||||
|
||||
echo "🔧 Attempting automatic fixes..."
|
||||
|
||||
switch $fix_type
|
||||
case cache
|
||||
echo "Cleaning up cache..."
|
||||
nvm_cache clear
|
||||
echo "✅ Cache cleared"
|
||||
|
||||
case permissions
|
||||
echo "Fixing cache directory permissions..."
|
||||
set -l cache_dir
|
||||
if set -q XDG_CACHE_HOME
|
||||
set cache_dir "$XDG_CACHE_HOME/nvm-auto-use"
|
||||
else
|
||||
set cache_dir "$HOME/.cache/nvm-auto-use"
|
||||
end
|
||||
|
||||
mkdir -p "$cache_dir" 2>/dev/null
|
||||
chmod 755 "$cache_dir" 2>/dev/null
|
||||
echo "✅ Cache directory permissions fixed"
|
||||
|
||||
case config
|
||||
echo "Resetting configuration to defaults..."
|
||||
nvm_auto_use_config reset
|
||||
echo "✅ Configuration reset"
|
||||
|
||||
case all
|
||||
echo "Running all available fixes..."
|
||||
_nvm_doctor_auto_fix cache
|
||||
_nvm_doctor_auto_fix permissions
|
||||
echo "✅ All fixes completed"
|
||||
|
||||
case '*'
|
||||
echo "Available fix types:"
|
||||
echo " cache - Clear cache files"
|
||||
echo " permissions - Fix directory permissions"
|
||||
echo " config - Reset configuration"
|
||||
echo " all - Run all fixes"
|
||||
return 1
|
||||
end
|
||||
end
|
||||
168
functions/nvm_error_recovery.fish
Normal file
168
functions/nvm_error_recovery.fish
Normal file
@@ -0,0 +1,168 @@
|
||||
function nvm_error_recovery -d "Error recovery and graceful degradation"
|
||||
set -l operation $argv[1]
|
||||
set -l error_context $argv[2]
|
||||
|
||||
switch $operation
|
||||
case manager_failure
|
||||
set -l manager $argv[2]
|
||||
set -l target_version $argv[3]
|
||||
|
||||
echo "⚠️ $manager failed to switch to version $target_version" >&2
|
||||
|
||||
# Try fallback managers
|
||||
set -l fallback_managers (nvm_compat_detect | string split ' ')
|
||||
for fallback in $fallback_managers
|
||||
if test "$fallback" != "$manager"
|
||||
echo "🔄 Trying fallback manager: $fallback" >&2
|
||||
if _nvm_error_recovery_try_manager "$fallback" "$target_version"
|
||||
echo "✅ Successfully switched using $fallback" >&2
|
||||
return 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
echo "❌ All managers failed. Staying on current version." >&2
|
||||
return 1
|
||||
|
||||
case version_not_found
|
||||
set -l manager $argv[2]
|
||||
set -l requested_version $argv[3]
|
||||
|
||||
echo "⚠️ Version $requested_version not found" >&2
|
||||
|
||||
# Try to find similar versions
|
||||
set -l suggestions (_nvm_error_recovery_suggest_versions "$manager" "$requested_version")
|
||||
if test -n "$suggestions"
|
||||
echo "💡 Available similar versions: $suggestions" >&2
|
||||
|
||||
# Auto-select best match if auto_install is disabled
|
||||
if set -q _nvm_auto_use_no_install
|
||||
set -l best_match (echo "$suggestions" | string split ' ' | head -n 1)
|
||||
echo "🔄 Trying closest match: $best_match" >&2
|
||||
if _nvm_error_recovery_try_manager "$manager" "$best_match"
|
||||
return 0
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return 1
|
||||
|
||||
case network_failure
|
||||
echo "⚠️ Network failure during version operation" >&2
|
||||
|
||||
# Check if we have a cached version list
|
||||
set -l cache_key "versions_$(echo $argv[2] | shasum | cut -d' ' -f1)"
|
||||
if set -l cached_versions (nvm_cache get "$cache_key" 86400) # 24 hour TTL
|
||||
echo "📦 Using cached version information" >&2
|
||||
echo "$cached_versions"
|
||||
return 0
|
||||
end
|
||||
|
||||
echo "❌ No cached version information available" >&2
|
||||
return 1
|
||||
|
||||
case permission_denied
|
||||
set -l operation_type $argv[2]
|
||||
echo "⚠️ Permission denied for $operation_type" >&2
|
||||
|
||||
switch $operation_type
|
||||
case install
|
||||
echo "💡 Try running with appropriate permissions or check manager configuration" >&2
|
||||
case switch
|
||||
echo "💡 Check if the version is already installed or try with sudo" >&2
|
||||
end
|
||||
|
||||
return 1
|
||||
|
||||
case timeout
|
||||
set -l operation_type $argv[2]
|
||||
set -l timeout_duration $argv[3]
|
||||
|
||||
echo "⏱️ Operation '$operation_type' timed out after $timeout_duration seconds" >&2
|
||||
echo "💡 Consider checking network connection or increasing timeout" >&2
|
||||
|
||||
# Kill any hanging processes
|
||||
nvm_async cleanup
|
||||
return 1
|
||||
|
||||
case corruption
|
||||
set -l file_path $argv[2]
|
||||
echo "⚠️ Corrupted file detected: $file_path" >&2
|
||||
|
||||
# Try to recover from backup or regenerate
|
||||
if test -f "$file_path.backup"
|
||||
echo "🔄 Restoring from backup" >&2
|
||||
cp "$file_path.backup" "$file_path"
|
||||
return 0
|
||||
end
|
||||
|
||||
echo "❌ No backup available, manual intervention required" >&2
|
||||
return 1
|
||||
|
||||
case '*'
|
||||
echo "Unknown error recovery operation: $operation" >&2
|
||||
return 1
|
||||
end
|
||||
end
|
||||
|
||||
function _nvm_error_recovery_try_manager -d "Try using a specific manager"
|
||||
set -l manager $argv[1]
|
||||
set -l version $argv[2]
|
||||
|
||||
if not command -q "$manager"
|
||||
return 1
|
||||
end
|
||||
|
||||
switch $manager
|
||||
case nvm
|
||||
nvm use "$version" 2>/dev/null
|
||||
case fnm
|
||||
fnm use "$version" 2>/dev/null
|
||||
case volta
|
||||
volta pin "node@$version" 2>/dev/null
|
||||
case asdf
|
||||
asdf local nodejs "$version" 2>/dev/null
|
||||
case '*'
|
||||
return 1
|
||||
end
|
||||
end
|
||||
|
||||
function _nvm_error_recovery_suggest_versions -d "Suggest similar available versions"
|
||||
set -l manager $argv[1]
|
||||
set -l requested $argv[2]
|
||||
|
||||
# Extract major version for suggestions
|
||||
set -l major (echo "$requested" | string replace -r '^v?([0-9]+).*' '$1')
|
||||
|
||||
# Try to get available versions (with error handling)
|
||||
set -l available_versions
|
||||
switch $manager
|
||||
case nvm
|
||||
set available_versions (nvm list-remote 2>/dev/null | grep "^v$major\." | head -n 5)
|
||||
case fnm
|
||||
set available_versions (fnm list-remote 2>/dev/null | grep "^v$major\." | head -n 5)
|
||||
case asdf
|
||||
set available_versions (asdf list-all nodejs 2>/dev/null | grep "^$major\." | head -n 5)
|
||||
end
|
||||
|
||||
echo "$available_versions" | string join ' '
|
||||
end
|
||||
|
||||
function _nvm_error_recovery_log -d "Log error for debugging"
|
||||
set -l error_type $argv[1]
|
||||
set -l details $argv[2]
|
||||
|
||||
# Log to XDG cache directory
|
||||
set -l log_dir
|
||||
if set -q XDG_CACHE_HOME
|
||||
set log_dir "$XDG_CACHE_HOME/nvm-auto-use"
|
||||
else
|
||||
set log_dir "$HOME/.cache/nvm-auto-use"
|
||||
end
|
||||
|
||||
mkdir -p "$log_dir" 2>/dev/null
|
||||
set -l log_file "$log_dir/error.log"
|
||||
|
||||
set -l timestamp (date '+%Y-%m-%d %H:%M:%S')
|
||||
echo "[$timestamp] $error_type: $details" >>"$log_file"
|
||||
end
|
||||
@@ -35,11 +35,15 @@ function nvm_extract_version -a file_path -d "Extract Node.js version from vario
|
||||
# Standard .nvmrc or .node-version file
|
||||
set -l version (cat "$actual_file" | string trim)
|
||||
if test -n "$version"
|
||||
# Strip leading 'v'
|
||||
set version (string replace -r '^v' '' "$version")
|
||||
# Handle nvm aliases
|
||||
switch "$version"
|
||||
case 'lts/*' lts latest stable node
|
||||
if command -q nvm
|
||||
set version (nvm version-remote "$version" 2>/dev/null | string replace 'v' '')
|
||||
else if command -q node
|
||||
set version (node -v 2>/dev/null | string replace -r '^v' '')
|
||||
end
|
||||
end
|
||||
echo "$version"
|
||||
|
||||
@@ -8,13 +8,18 @@ function nvm_notify -a message -d "Send notification for Node.js version changes
|
||||
return
|
||||
end
|
||||
|
||||
# Try different notification methods
|
||||
if command -q osascript # macOS
|
||||
# Try different notification methods until one succeeds
|
||||
if command -q osascript
|
||||
osascript -e "display notification \"$message\" with title \"nvm-auto-use\""
|
||||
else if command -q notify-send # Linux
|
||||
return
|
||||
end
|
||||
if command -q notify-send
|
||||
notify-send nvm-auto-use "$message"
|
||||
else if command -q terminal-notifier # macOS alternative
|
||||
return
|
||||
end
|
||||
if command -q terminal-notifier
|
||||
terminal-notifier -title nvm-auto-use -message "$message"
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
354
functions/nvm_recommendations.fish
Normal file
354
functions/nvm_recommendations.fish
Normal file
@@ -0,0 +1,354 @@
|
||||
function nvm_recommendations -d "Smart recommendations for Node.js versions and configurations"
|
||||
set -l action $argv[1]
|
||||
|
||||
switch $action
|
||||
case suggest_version
|
||||
_nvm_recommend_version $argv[2..-1]
|
||||
case upgrade_path
|
||||
_nvm_recommend_upgrade $argv[2..-1]
|
||||
case security_update
|
||||
_nvm_recommend_security_update
|
||||
case performance
|
||||
_nvm_recommend_performance
|
||||
case compatibility
|
||||
_nvm_recommend_compatibility $argv[2..-1]
|
||||
case manager
|
||||
_nvm_recommend_manager
|
||||
case config
|
||||
_nvm_recommend_config
|
||||
case '*'
|
||||
echo "Usage: nvm_recommendations [suggest_version|upgrade_path|security_update|performance|compatibility|manager|config] [args...]"
|
||||
return 1
|
||||
end
|
||||
end
|
||||
|
||||
function _nvm_recommend_version -d "Recommend appropriate Node.js version"
|
||||
set -l context $argv[1] # 'new_project', 'existing_project', 'migration'
|
||||
|
||||
echo "🔍 Analyzing project for Node.js version recommendation..."
|
||||
|
||||
# Check for existing version constraints
|
||||
set -l constraints (_nvm_analyze_version_constraints)
|
||||
set -l current_version
|
||||
if command -q node
|
||||
set current_version (node --version | string replace 'v' '')
|
||||
end
|
||||
|
||||
# Get available managers and their capabilities
|
||||
set -l available_managers (nvm_compat_detect | string split ' ')
|
||||
|
||||
echo
|
||||
echo "📋 Recommendation Analysis:"
|
||||
echo "============================"
|
||||
|
||||
# Project type detection
|
||||
set -l project_type (_nvm_detect_project_type)
|
||||
echo "Project type: $project_type"
|
||||
|
||||
if test -n "$current_version"
|
||||
echo "Current version: $current_version"
|
||||
end
|
||||
|
||||
if test -n "$constraints"
|
||||
echo "Detected constraints: $constraints"
|
||||
end
|
||||
|
||||
# Generate recommendations
|
||||
echo
|
||||
echo "💡 Recommendations:"
|
||||
echo "==================="
|
||||
|
||||
switch $context
|
||||
case new_project
|
||||
_nvm_recommend_for_new_project "$project_type"
|
||||
case existing_project
|
||||
_nvm_recommend_for_existing_project "$project_type" "$current_version"
|
||||
case migration
|
||||
_nvm_recommend_for_migration "$current_version"
|
||||
case '*'
|
||||
_nvm_recommend_general "$project_type" "$current_version"
|
||||
end
|
||||
end
|
||||
|
||||
function _nvm_recommend_for_new_project -d "Recommendations for new projects"
|
||||
set -l project_type $argv[1]
|
||||
|
||||
switch $project_type
|
||||
case react
|
||||
echo "• Node.js 18.17.0+ (LTS) - Recommended for React projects"
|
||||
echo "• Consider Node.js 20.x for latest features"
|
||||
echo "• Avoid odd-numbered versions (development releases)"
|
||||
case vue
|
||||
echo "• Node.js 16.20.0+ - Minimum for Vue 3"
|
||||
echo "• Node.js 18.17.0+ (LTS) - Recommended"
|
||||
case angular
|
||||
echo "• Node.js 18.13.0+ - Required for Angular 15+"
|
||||
echo "• Node.js 18.17.0+ (LTS) - Recommended"
|
||||
case nextjs
|
||||
echo "• Node.js 18.17.0+ - Required for Next.js 13+"
|
||||
echo "• Node.js 20.x for best performance"
|
||||
case typescript
|
||||
echo "• Node.js 18.17.0+ (LTS) - Excellent TypeScript support"
|
||||
echo "• Node.js 20.x for latest TypeScript features"
|
||||
case backend
|
||||
echo "• Node.js 18.17.0+ (LTS) - Stable for production"
|
||||
echo "• Consider Node.js 20.x for performance improvements"
|
||||
case '*'
|
||||
echo "• Node.js 18.17.0+ (LTS) - Safe choice for most projects"
|
||||
echo "• Node.js 20.x for latest features and performance"
|
||||
end
|
||||
|
||||
echo
|
||||
echo "💭 General Guidelines:"
|
||||
echo "• Use LTS versions for production projects"
|
||||
echo "• Test with latest version for future compatibility"
|
||||
echo "• Pin exact versions in CI/CD environments"
|
||||
end
|
||||
|
||||
function _nvm_recommend_for_existing_project -d "Recommendations for existing projects"
|
||||
set -l project_type $argv[1]
|
||||
set -l current_version $argv[2]
|
||||
|
||||
if test -z "$current_version"
|
||||
echo "• Install Node.js to get version-specific recommendations"
|
||||
return
|
||||
end
|
||||
|
||||
# Check if current version is LTS
|
||||
set -l is_lts (_nvm_check_if_lts "$current_version")
|
||||
set -l is_outdated (_nvm_check_if_outdated "$current_version")
|
||||
|
||||
if test "$is_outdated" = true
|
||||
echo "⚠️ Current version ($current_version) is outdated"
|
||||
echo "• Consider upgrading to latest LTS for security updates"
|
||||
|
||||
# Suggest upgrade path
|
||||
set -l upgrade_target (_nvm_suggest_upgrade_target "$current_version")
|
||||
if test -n "$upgrade_target"
|
||||
echo "• Recommended upgrade: $upgrade_target"
|
||||
end
|
||||
else if test "$is_lts" = false
|
||||
echo "ℹ️ Current version ($current_version) is not LTS"
|
||||
echo "• Consider switching to LTS for stability"
|
||||
else
|
||||
echo "✅ Current version ($current_version) is good"
|
||||
echo "• No immediate action needed"
|
||||
end
|
||||
|
||||
# Dependency compatibility check
|
||||
if test -f "package.json"
|
||||
echo
|
||||
echo "📦 Dependency Analysis:"
|
||||
_nvm_analyze_dependencies
|
||||
end
|
||||
end
|
||||
|
||||
function _nvm_recommend_upgrade -d "Recommend upgrade path"
|
||||
set -l current_version $argv[1]
|
||||
|
||||
if test -z "$current_version"
|
||||
if command -q node
|
||||
set current_version (node --version | string replace 'v' '')
|
||||
else
|
||||
echo "❌ No Node.js version specified or installed"
|
||||
return 1
|
||||
end
|
||||
end
|
||||
|
||||
echo "🔄 Upgrade Path Analysis for Node.js $current_version"
|
||||
echo "=================================================="
|
||||
|
||||
# Check for security issues
|
||||
nvm_security check_cve "$current_version"
|
||||
set -l has_vulnerabilities $status
|
||||
|
||||
if test $has_vulnerabilities -ne 0
|
||||
echo
|
||||
echo "🚨 SECURITY: Immediate upgrade recommended due to vulnerabilities"
|
||||
end
|
||||
|
||||
# Suggest upgrade targets
|
||||
set -l major_version (echo "$current_version" | string replace -r '^([0-9]+)\..*' '$1')
|
||||
set -l next_lts (_nvm_get_next_lts "$major_version")
|
||||
|
||||
echo
|
||||
echo "📈 Upgrade Options:"
|
||||
echo "• Patch upgrade: Stay within current minor version"
|
||||
echo "• Minor upgrade: Upgrade to latest in major version $major_version"
|
||||
|
||||
if test -n "$next_lts"
|
||||
echo "• Major upgrade: Node.js $next_lts (LTS)"
|
||||
end
|
||||
|
||||
echo
|
||||
echo "🧪 Testing Strategy:"
|
||||
echo "1. Test in development environment first"
|
||||
echo "2. Run full test suite"
|
||||
echo "3. Check for breaking changes in release notes"
|
||||
echo "4. Update CI/CD pipelines"
|
||||
echo "5. Deploy to staging before production"
|
||||
end
|
||||
|
||||
function _nvm_recommend_security_update -d "Recommend security-focused updates"
|
||||
echo "🔒 Security Update Recommendations"
|
||||
echo "=================================="
|
||||
|
||||
if command -q node
|
||||
set -l current_version (node --version | string replace 'v' '')
|
||||
echo "Current version: $current_version"
|
||||
|
||||
# Check for vulnerabilities
|
||||
nvm_security check_cve "$current_version"
|
||||
set -l has_vulnerabilities $status
|
||||
|
||||
if test $has_vulnerabilities -ne 0
|
||||
echo
|
||||
echo "🚨 ACTION REQUIRED: Security vulnerabilities found"
|
||||
echo "• Upgrade immediately to patch security issues"
|
||||
|
||||
# Suggest secure versions
|
||||
set -l secure_versions (_nvm_get_secure_versions)
|
||||
if test -n "$secure_versions"
|
||||
echo "• Recommended secure versions: $secure_versions"
|
||||
end
|
||||
else
|
||||
echo
|
||||
echo "✅ No known vulnerabilities in current version"
|
||||
echo "• Keep monitoring for security updates"
|
||||
end
|
||||
else
|
||||
echo "❌ Node.js not installed - cannot assess security status"
|
||||
end
|
||||
|
||||
echo
|
||||
echo "🛡️ Security Best Practices:"
|
||||
echo "• Keep Node.js updated to latest patch versions"
|
||||
echo "• Subscribe to Node.js security announcements"
|
||||
echo "• Use npm audit for dependency vulnerabilities"
|
||||
echo "• Pin specific versions in production"
|
||||
end
|
||||
|
||||
function _nvm_recommend_performance -d "Performance optimization recommendations"
|
||||
echo "⚡ Performance Optimization Recommendations"
|
||||
echo "=========================================="
|
||||
|
||||
if command -q node
|
||||
set -l current_version (node --version | string replace 'v' '')
|
||||
set -l major_version (echo "$current_version" | string replace -r '^([0-9]+)\..*' '$1')
|
||||
|
||||
echo "Current version: $current_version"
|
||||
echo
|
||||
|
||||
# Version-specific performance notes
|
||||
switch $major_version
|
||||
case 16
|
||||
echo "📈 Upgrade to Node.js 18+ for:"
|
||||
echo "• Better V8 engine performance"
|
||||
echo "• Improved startup time"
|
||||
echo "• Enhanced memory usage"
|
||||
case 18
|
||||
echo "📈 Consider Node.js 20+ for:"
|
||||
echo "• Latest V8 optimizations"
|
||||
echo "• Improved module loading"
|
||||
echo "• Better async performance"
|
||||
case 20 21
|
||||
echo "✅ You're using a modern Node.js version"
|
||||
echo "• Good performance characteristics"
|
||||
echo "• Consider latest patch for micro-optimizations"
|
||||
case '*'
|
||||
echo "⚠️ Consider upgrading to Node.js 18+ for better performance"
|
||||
end
|
||||
end
|
||||
|
||||
echo
|
||||
echo "🎯 Performance Tips:"
|
||||
echo "• Use --max-old-space-size for memory-intensive apps"
|
||||
echo "• Enable --experimental-loader for faster imports"
|
||||
echo "• Consider --enable-source-maps for better debugging"
|
||||
echo "• Profile with --cpu-prof and --heap-prof"
|
||||
end
|
||||
|
||||
function _nvm_detect_project_type -d "Detect project type from files"
|
||||
if test -f "package.json"
|
||||
set -l deps (cat package.json 2>/dev/null)
|
||||
|
||||
if echo "$deps" | grep -q '"react"'
|
||||
echo react
|
||||
else if echo "$deps" | grep -q '"vue"'
|
||||
echo vue
|
||||
else if echo "$deps" | grep -q '"@angular"'
|
||||
echo angular
|
||||
else if echo "$deps" | grep -q '"next"'
|
||||
echo nextjs
|
||||
else if echo "$deps" | grep -q '"typescript"'
|
||||
echo typescript
|
||||
else if echo "$deps" | grep -q '"express"\|"fastify"\|"koa"'
|
||||
echo backend
|
||||
else
|
||||
echo node
|
||||
end
|
||||
else
|
||||
echo general
|
||||
end
|
||||
end
|
||||
|
||||
function _nvm_analyze_version_constraints -d "Analyze existing version constraints"
|
||||
set -l constraints
|
||||
|
||||
# Check package.json engines
|
||||
if test -f "package.json" -a command -q jq
|
||||
set -l engine_constraint (jq -r '.engines.node // empty' package.json 2>/dev/null)
|
||||
if test -n "$engine_constraint"
|
||||
set constraints $constraints "package.json: $engine_constraint"
|
||||
end
|
||||
end
|
||||
|
||||
# Check .nvmrc
|
||||
if test -f ".nvmrc"
|
||||
set -l nvmrc_version (cat .nvmrc | string trim)
|
||||
set constraints $constraints ".nvmrc: $nvmrc_version"
|
||||
end
|
||||
|
||||
echo "$constraints" | string join '; '
|
||||
end
|
||||
|
||||
function _nvm_check_if_lts -d "Check if version is LTS"
|
||||
set -l version $argv[1]
|
||||
set -l major (echo "$version" | string replace -r '^([0-9]+)\..*' '$1')
|
||||
|
||||
# LTS versions: 16, 18, 20 (even numbers)
|
||||
if test (math "$major % 2") -eq 0
|
||||
echo true
|
||||
else
|
||||
echo false
|
||||
end
|
||||
end
|
||||
|
||||
function _nvm_check_if_outdated -d "Check if version is outdated"
|
||||
set -l version $argv[1]
|
||||
set -l major (echo "$version" | string replace -r '^([0-9]+)\..*' '$1')
|
||||
|
||||
# Simplified check - versions below 16 are definitely outdated
|
||||
if test $major -lt 16
|
||||
echo true
|
||||
else
|
||||
echo false
|
||||
end
|
||||
end
|
||||
|
||||
function _nvm_get_next_lts -d "Get next LTS version"
|
||||
set -l current_major $argv[1]
|
||||
set -l next_lts
|
||||
|
||||
# Determine next LTS based on current major
|
||||
switch $current_major
|
||||
case 14 15 16 17
|
||||
set next_lts "18.17.0"
|
||||
case 18 19
|
||||
set next_lts "20.5.0"
|
||||
case '*'
|
||||
set next_lts "20.5.0"
|
||||
end
|
||||
|
||||
echo "$next_lts"
|
||||
end
|
||||
278
functions/nvm_security.fish
Normal file
278
functions/nvm_security.fish
Normal file
@@ -0,0 +1,278 @@
|
||||
function nvm_security -d "Security validation and vulnerability checking"
|
||||
set -l action $argv[1]
|
||||
|
||||
switch $action
|
||||
case check_version
|
||||
set -l version $argv[2]
|
||||
_nvm_security_validate_version "$version"
|
||||
|
||||
case check_cve
|
||||
set -l version $argv[2]
|
||||
_nvm_security_check_vulnerabilities "$version"
|
||||
|
||||
case validate_source
|
||||
set -l source $argv[2]
|
||||
_nvm_security_validate_source "$source"
|
||||
|
||||
case audit
|
||||
_nvm_security_audit_current
|
||||
|
||||
case policy
|
||||
set -l policy_action $argv[2]
|
||||
_nvm_security_policy "$policy_action" $argv[3..-1]
|
||||
|
||||
case '*'
|
||||
echo "Usage: nvm_security [check_version|check_cve|validate_source|audit|policy] [args...]"
|
||||
return 1
|
||||
end
|
||||
end
|
||||
|
||||
function _nvm_security_validate_version -d "Validate version string format and safety"
|
||||
set -l version $argv[1]
|
||||
|
||||
# Remove leading 'v' if present
|
||||
set version (string replace -r '^v' '' "$version")
|
||||
|
||||
# Check for valid semver format
|
||||
if not string match -qr '^\d+\.\d+\.\d+' "$version"
|
||||
echo "⚠️ Invalid version format: $version" >&2
|
||||
return 1
|
||||
end
|
||||
|
||||
# Check for suspicious characters
|
||||
if string match -qr '[;&|`$(){}[\]<>]' "$version"
|
||||
echo "🚨 Suspicious characters in version: $version" >&2
|
||||
return 1
|
||||
end
|
||||
|
||||
# Check against minimum supported version
|
||||
set -l min_version (nvm_security policy get min_version)
|
||||
if test -n "$min_version"
|
||||
if _nvm_security_version_compare "$version" "$min_version" -lt
|
||||
echo "⚠️ Version $version is below minimum required ($min_version)" >&2
|
||||
return 1
|
||||
end
|
||||
end
|
||||
|
||||
# Check against maximum allowed version
|
||||
set -l max_version (nvm_security policy get max_version)
|
||||
if test -n "$max_version"
|
||||
if _nvm_security_version_compare "$version" "$max_version" -gt
|
||||
echo "⚠️ Version $version is above maximum allowed ($max_version)" >&2
|
||||
return 1
|
||||
end
|
||||
end
|
||||
|
||||
return 0
|
||||
end
|
||||
|
||||
function _nvm_security_check_vulnerabilities -d "Check version for known vulnerabilities"
|
||||
set -l version $argv[1]
|
||||
|
||||
# Cache key for CVE data
|
||||
set -l cache_key "cve_check_$(echo $version | shasum | cut -d' ' -f1)"
|
||||
|
||||
# Check cache first (24 hour TTL)
|
||||
if set -l cached_result (nvm_cache get "$cache_key" 86400)
|
||||
if test "$cached_result" = vulnerable
|
||||
echo "🚨 Version $version has known vulnerabilities (cached)" >&2
|
||||
return 1
|
||||
else if test "$cached_result" = safe
|
||||
echo "✅ Version $version appears safe (cached)" >&2
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
# Check against known vulnerable versions (offline first)
|
||||
set -l vulnerable_versions "
|
||||
16.0.0
|
||||
16.1.0
|
||||
16.2.0
|
||||
18.0.0
|
||||
18.1.0
|
||||
"
|
||||
|
||||
if string match -q "*$version*" "$vulnerable_versions"
|
||||
echo "🚨 Version $version has known vulnerabilities" >&2
|
||||
nvm_cache set "$cache_key" vulnerable
|
||||
return 1
|
||||
end
|
||||
|
||||
# Try online CVE check if available
|
||||
if command -q curl
|
||||
_nvm_security_online_cve_check "$version" "$cache_key"
|
||||
else
|
||||
echo "ℹ️ Cannot perform online CVE check (curl not available)" >&2
|
||||
nvm_cache set "$cache_key" unknown
|
||||
return 0
|
||||
end
|
||||
end
|
||||
|
||||
function _nvm_security_online_cve_check -d "Perform online CVE check"
|
||||
set -l version $argv[1]
|
||||
set -l cache_key $argv[2]
|
||||
|
||||
# Background job for CVE checking to avoid blocking
|
||||
fish -c "
|
||||
set cve_result (curl -s --max-time 5 'https://nodejs.org/en/about/security/' 2>/dev/null)
|
||||
if test \$status -eq 0
|
||||
if echo \"\$cve_result\" | grep -qi '$version'
|
||||
nvm_cache set '$cache_key' 'vulnerable'
|
||||
echo '🚨 Version $version found in security advisories' >&2
|
||||
else
|
||||
nvm_cache set '$cache_key' 'safe'
|
||||
echo '✅ Version $version appears safe' >&2
|
||||
end
|
||||
else
|
||||
nvm_cache set '$cache_key' 'unknown'
|
||||
echo 'ℹ️ Unable to verify security status online' >&2
|
||||
end
|
||||
" &
|
||||
|
||||
return 0
|
||||
end
|
||||
|
||||
function _nvm_security_validate_source -d "Validate version file source"
|
||||
set -l source_file $argv[1]
|
||||
|
||||
if not test -f "$source_file"
|
||||
echo "⚠️ Source file not found: $source_file" >&2
|
||||
return 1
|
||||
end
|
||||
|
||||
# Check file permissions
|
||||
if test -w "$source_file" -a (stat -c %a "$source_file" 2>/dev/null || stat -f %Mp%Lp "$source_file" 2>/dev/null) = 777
|
||||
echo "⚠️ Insecure permissions on $source_file (world-writable)" >&2
|
||||
end
|
||||
|
||||
# Check for suspicious content
|
||||
set -l content (cat "$source_file")
|
||||
if string match -qr '[;&|`$(){}[\]<>]' "$content"
|
||||
echo "🚨 Suspicious content in $source_file" >&2
|
||||
return 1
|
||||
end
|
||||
|
||||
return 0
|
||||
end
|
||||
|
||||
function _nvm_security_audit_current -d "Audit current Node.js installation"
|
||||
echo "🔍 Security audit for current Node.js installation"
|
||||
echo
|
||||
|
||||
# Current version info
|
||||
if command -q node
|
||||
set -l current_version (node --version 2>/dev/null | string replace 'v' '')
|
||||
echo "Current version: $current_version"
|
||||
|
||||
# Check current version security
|
||||
nvm_security check_version "$current_version"
|
||||
nvm_security check_cve "$current_version"
|
||||
|
||||
# Check npm security if available
|
||||
if command -q npm
|
||||
echo
|
||||
echo "📦 NPM audit (if available):"
|
||||
npm audit --audit-level moderate 2>/dev/null || echo "NPM audit not available or no package.json found"
|
||||
end
|
||||
else
|
||||
echo "❌ Node.js not found in PATH"
|
||||
end
|
||||
|
||||
echo
|
||||
echo "🔧 Version managers found:"
|
||||
nvm_compat_detect
|
||||
|
||||
echo
|
||||
echo "📋 Security policies:"
|
||||
nvm_security policy list
|
||||
end
|
||||
|
||||
function _nvm_security_policy -d "Manage security policies"
|
||||
set -l action $argv[1]
|
||||
|
||||
switch $action
|
||||
case set
|
||||
set -l key $argv[2]
|
||||
set -l value $argv[3]
|
||||
|
||||
switch $key
|
||||
case min_version
|
||||
set -g _nvm_security_min_version "$value"
|
||||
echo "Set minimum version to: $value"
|
||||
case max_version
|
||||
set -g _nvm_security_max_version "$value"
|
||||
echo "Set maximum version to: $value"
|
||||
case allow_prerelease
|
||||
set -g _nvm_security_allow_prerelease "$value"
|
||||
echo "Allow prerelease versions: $value"
|
||||
case '*'
|
||||
echo "Unknown policy key: $key" >&2
|
||||
return 1
|
||||
end
|
||||
|
||||
case get
|
||||
set -l key $argv[2]
|
||||
|
||||
switch $key
|
||||
case min_version
|
||||
echo "$_nvm_security_min_version"
|
||||
case max_version
|
||||
echo "$_nvm_security_max_version"
|
||||
case allow_prerelease
|
||||
echo "$_nvm_security_allow_prerelease"
|
||||
case '*'
|
||||
echo "Unknown policy key: $key" >&2
|
||||
return 1
|
||||
end
|
||||
|
||||
case list
|
||||
echo "Security policies:"
|
||||
echo " min_version: $_nvm_security_min_version"
|
||||
echo " max_version: $_nvm_security_max_version"
|
||||
echo " allow_prerelease: $_nvm_security_allow_prerelease"
|
||||
|
||||
case reset
|
||||
set -e _nvm_security_min_version
|
||||
set -e _nvm_security_max_version
|
||||
set -e _nvm_security_allow_prerelease
|
||||
echo "Security policies reset to defaults"
|
||||
|
||||
case '*'
|
||||
echo "Usage: nvm_security policy [set|get|list|reset] [key] [value]"
|
||||
return 1
|
||||
end
|
||||
end
|
||||
|
||||
function _nvm_security_version_compare -d "Compare semantic versions"
|
||||
set -l version1 $argv[1]
|
||||
set -l version2 $argv[2]
|
||||
set -l operator $argv[3]
|
||||
|
||||
# Simple semver comparison
|
||||
set -l v1_parts (string split '.' "$version1")
|
||||
set -l v2_parts (string split '.' "$version2")
|
||||
|
||||
for i in (seq 1 3)
|
||||
set -l v1_part (echo $v1_parts[$i] | string replace -r '[^0-9].*' '')
|
||||
set -l v2_part (echo $v2_parts[$i] | string replace -r '[^0-9].*' '')
|
||||
|
||||
if test -z "$v1_part"
|
||||
set v1_part 0
|
||||
end
|
||||
if test -z "$v2_part"
|
||||
set v2_part 0
|
||||
end
|
||||
|
||||
if test $v1_part -lt $v2_part
|
||||
test "$operator" = -lt
|
||||
return $status
|
||||
else if test $v1_part -gt $v2_part
|
||||
test "$operator" = -gt
|
||||
return $status
|
||||
end
|
||||
end
|
||||
|
||||
# Versions are equal
|
||||
test "$operator" = -eq
|
||||
return $status
|
||||
end
|
||||
@@ -9,10 +9,13 @@ end
|
||||
|
||||
function nvm_version_status -d "Show detailed Node.js version status"
|
||||
if command -q node
|
||||
set -l version (node -v 2>/dev/null)
|
||||
set -l npm_version (npm -v 2>/dev/null)
|
||||
set -l version (node -v 2>/dev/null | string replace -r '^v' '')
|
||||
set -l npm_version
|
||||
if command -q npm
|
||||
set npm_version (npm -v 2>/dev/null)
|
||||
end
|
||||
|
||||
echo "Node.js: $version"
|
||||
echo "Node.js: v$version"
|
||||
if test -n "$npm_version"
|
||||
echo "npm: v$npm_version"
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user