From b515275407517a951c90ada9f88795c4ee776e2c Mon Sep 17 00:00:00 2001 From: sebseb7 Date: Tue, 12 Aug 2025 18:34:07 +0000 Subject: [PATCH] Enhance CLI terminal integration and output handling in InkApp. Introduce terminalService for managing PTY backend, including resizing and updating terminal output. Implement ANSI stripping and tab expansion for accurate line rendering. Improve state management for terminal, logs, and LLM output, ensuring responsive UI updates and error handling during input submission. --- cli-ink.js | 13 + out1 | 4646 ++++++++++++++++++++++++++++++++++++++++ src/terminalService.js | 123 ++ src/ui/InkApp.jsx | 169 +- 4 files changed, 4935 insertions(+), 16 deletions(-) create mode 100644 out1 create mode 100644 src/terminalService.js diff --git a/cli-ink.js b/cli-ink.js index 37e530d..b06fb1a 100755 --- a/cli-ink.js +++ b/cli-ink.js @@ -3,6 +3,10 @@ import 'dotenv/config'; import React from 'react'; import { render } from 'ink'; import InkApp from './src/ui/InkApp.jsx'; +import terminalService from './src/terminalService.js'; + +// Start the PTY backend independent from UI lifecycle +terminalService.start(); const { unmount } = render(React.createElement(InkApp)); @@ -14,6 +18,7 @@ if (process.stdin.isTTY) { const exitCleanly = () => { unmount(); + try { terminalService.dispose(); } catch { } try { process.stdin.setRawMode(false); } catch { } process.exit(0); }; @@ -21,6 +26,10 @@ if (process.stdin.isTTY) { const onData = (data) => { const buffer = Buffer.isBuffer(data) ? data : Buffer.from(String(data)); for (const byte of buffer) { + // Ctrl-C (ETX) + if (byte === 0x03) { + return exitCleanly(); + } if (!escPending) { if (byte === 0x1b) { // ESC escPending = true; @@ -42,6 +51,10 @@ if (process.stdin.isTTY) { }; process.stdin.on('data', onData); + + // Also handle SIGINT in case raw mode changes or comes from elsewhere + const onSigint = () => exitCleanly(); + process.on('SIGINT', onSigint); } diff --git a/out1 b/out1 new file mode 100644 index 0000000..93443d4 --- /dev/null +++ b/out1 @@ -0,0 +1,4646 @@ +BASH=/bin/bash +BASHOPTS=checkwinsize:cmdhist:complete_fullquote:expand_aliases:extquote:force_fignore:globasciiranges:globskipdots:hostcomplete:interactive_comments:patsub_replacement:progcomp:promptvars:sourcepath +BASH_ALIASES=() +BASH_ARGC=([0]="0") +BASH_ARGV=() +BASH_CMDS=() +BASH_LINENO=() +BASH_LOADABLES_PATH=/usr/local/lib/bash:/usr/lib/bash:/opt/local/lib/bash:/usr/pkg/lib/bash:/opt/pkg/lib/bash:. +BASH_SOURCE=() +BASH_VERSINFO=([0]="5" [1]="2" [2]="15" [3]="1" [4]="release" [5]="x86_64-pc-linux-gnu") +BASH_VERSION='5.2.15(1)-release' +BROWSER=/home/node/.cursor-server/bin/e50823e9ded15fddfd743c7122b4724130c25df0/bin/helpers/browser.sh +COLOR=1 +COLORTERM=truecolor +COLUMNS=117 +╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ +DIRSTACK=() +EDITOR=vi +EUID=1000 +EXA_API_KEY=1513ba88-5280-402b-9da3-e060d38f96d8 +GIT_ASKPASS=/home/node/.cursor-server/bin/e50823e9ded15fddfd743c7122b4724130c25df0/extensions/git/dist/askpass.sh +GIT_EDITOR='code --wait' +GROUPS=() +HISTFILE=/home/node/.bash_history +HISTFILESIZE=500 +HISTSIZE=500 +HOME=/home/node +HOSTNAME=e5f89d61e870 +HOSTTYPE=x86_64 +IFS=$' \t\n' +INIT_CWD=/workspaces/aiTools +LANG=en_US.UTF-8 +LINES=32 +LS_COLORS='rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:mi=00:su=37;41:sg=30;43:ca=00:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arc=01;31:*.arj=01;31:*.taz=01;31:*.lha=01;31:*.lz4=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.tzo=01;31:*.t7z=01;31:*.zip=01;31:*.z=01;31:*.dz=01;31:*.gz=01;31:*.lrz=01;31:*.lz=01;31:*.lzo=01;31:*.xz=01;31:*.zst=01;31:*.tzst=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.alz=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.cab=01;31:*.wim=01;31:*.swm=01;31:*.dwm=01;31:*.esd=01;31:*.avif=01;35:*.jpg=01;35:*.jpeg=01;35:*.mjpg=01;35:*.mjpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.webp=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.m4a=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.oga=00;36:*.opus=00;36:*.spx=00;36:*.xspf=00;36:*~=00;90:*#=00;90:*.bak=00;90:*.old=00;90:*.orig=00;90:*.part=00;90:*.rej=00;90:*.swp=00;90:*.tmp=00;90:*.dpkg-dist=00;90:*.dpkg-old=00;90:*.ucf-dist=00;90:*.ucf-new=00;90:*.ucf-old=00;90:*.rpmnew=00;90:*.rpmorig=00;90:*.rpmsave=00;90:' +MACHTYPE=x86_64-pc-linux-gnu +MAILCHECK=60 +NODE=/usr/local/bin/node +NODE_ENV=development +NODE_VERSION=24.4.0 +NVM_CD_FLAGS= +NVM_DIR=/usr/local/share/nvm +NVM_RC_VERSION= +NVM_SYMLINK_CURRENT=true +OLDPWD=/home/node/.cursor-server/bin/e50823e9ded15fddfd743c7122b4724130c25df0 +OPENAI_API_KEY=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 +OPTERR=1 +OPTIND=1 +OSTYPE=linux-gnu +PATH=/workspaces/aiTools/node_modules/.bin:/workspaces/node_modules/.bin:/node_modules/.bin:/usr/local/lib/node_modules/npm/node_modules/@npmcli/run-script/lib/node-gyp-bin:/home/node/.cursor-server/bin/e50823e9ded15fddfd743c7122b4724130c25df0/bin/remote-cli:/usr/local/share/nvm/current/bin:/usr/local/share/npm-global/bin:/home/node/.cursor-server/bin/e50823e9ded15fddfd743c7122b4724130c25df0/bin/remote-cli:/usr/local/share/nvm/current/bin:/usr/local/share/npm-global/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/node/.local/bin +PIPESTATUS=([0]="0" [1]="1") +PPID=228171 +PROMPT_DIRTRIM=4 +PS1='bash> ' +PS2='> ' +PS4='+ ' +PWD=/workspaces/aiTools +SHELL=/bin/bash +SHELLOPTS=braceexpand:emacs:hashall:histexpand:history:interactive-comments:monitor +SHLVL=3 +TERM=xterm-256color +TERM_PROGRAM=vscode +TERM_PROGRAM_VERSION=1.4.3 +UID=1000 +USER=node +VSCODE_GIT_ASKPASS_EXTRA_ARGS= +VSCODE_GIT_ASKPASS_MAIN=/home/node/.cursor-server/bin/e50823e9ded15fddfd743c7122b4724130c25df0/extensions/git/dist/askpass-main.js +VSCODE_GIT_ASKPASS_NODE=/home/node/.cursor-server/bin/e50823e9ded15fddfd743c7122b4724130c25df0/node +VSCODE_GIT_IPC_HANDLE=/tmp/vscode-git-b68c2479f1.sock +VSCODE_IPC_HOOK_CLI=/tmp/vscode-ipc-2e29b891-6cf6-49df-87e1-858c8ef3de54.sock +YARN_VERSION=1.22.22 +_='PS1=bash> ' +npm_command=run +npm_config_cache=/home/node/.npm +npm_config_global_prefix=/usr/local/share/npm-global +npm_config_globalconfig=/usr/local/share/npm-global/etc/npmrc +npm_config_init_module=/home/node/.npm-init.js +npm_config_local_prefix=/workspaces/aiTools +npm_config_node_gyp=/usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-gyp.js +npm_config_noproxy= +npm_config_npm_version=11.4.2 +npm_config_prefix=/usr/local/share/npm-global +npm_config_user_agent='npm/11.4.2 node/v24.4.0 linux x64 workspaces/false' +npm_config_userconfig=/home/node/.npmrc +npm_execpath=/usr/local/lib/node_modules/npm/bin/npm-cli.js +npm_lifecycle_event=start:ink +npm_lifecycle_script='tsx cli-ink.js' +npm_node_execpath=/usr/local/bin/node +npm_package_json=/workspaces/aiTools/package.json +npm_package_name=aitools +npm_package_version=1.0.0 +__nvm () +{ + declare previous_word; + previous_word="${COMP_WORDS[COMP_CWORD - 1]}"; + case "${previous_word}" in + use | run | exec | ls | list | uninstall) + __nvm_installed_nodes + ;; + alias | unalias) + __nvm_alias + ;; + *) + __nvm_commands + ;; + esac; + return 0 +} +__nvm_alias () +{ + __nvm_generate_completion "$(__nvm_aliases)" +} +__nvm_aliases () +{ + declare aliases; + aliases=""; + if [ -d "${NVM_DIR}/alias" ]; then + aliases="$(command cd "${NVM_DIR}/alias" && command find "${PWD}" -type f | command sed "s:${PWD}/::")"; + fi; + echo "${aliases} node stable unstable iojs" +} +__nvm_commands () +{ + declare current_word; + declare command; + current_word="${COMP_WORDS[COMP_CWORD]}"; + COMMANDS=' + help install uninstall use run exec + alias unalias reinstall-packages + current list ls list-remote ls-remote + install-latest-npm + cache deactivate unload + version version-remote which'; + if [ ${#COMP_WORDS[@]} == 4 ]; then + command="${COMP_WORDS[COMP_CWORD - 2]}"; + case "${command}" in + alias) + __nvm_installed_nodes + ;; + esac; + else + case "${current_word}" in + -*) + __nvm_options + ;; + *) + __nvm_generate_completion "${COMMANDS}" + ;; + esac; + fi +} +__nvm_generate_completion () +{ + declare current_word; + current_word="${COMP_WORDS[COMP_CWORD]}"; + COMPREPLY=($(compgen -W "$1" -- "${current_word}")); + return 0 +} +__nvm_installed_nodes () +{ + __nvm_generate_completion "$(nvm_ls) $(__nvm_aliases)" +} +__nvm_options () +{ + OPTIONS=''; + __nvm_generate_completion "${OPTIONS}" +} +nvm () +{ + if [ "$#" -lt 1 ]; then + nvm --help; + return; + fi; + local DEFAULT_IFS; + DEFAULT_IFS=" $(nvm_echo t | command tr t \\t) +"; + if [ "${-#*e}" != "$-" ]; then + set +e; + local EXIT_CODE; + IFS="${DEFAULT_IFS}" nvm "$@"; + EXIT_CODE="$?"; + set -e; + return "$EXIT_CODE"; + else + if [ "${-#*a}" != "$-" ]; then + set +a; + local EXIT_CODE; + IFS="${DEFAULT_IFS}" nvm "$@"; + EXIT_CODE="$?"; + set -a; + return "$EXIT_CODE"; + else + if [ -n "${BASH-}" ] && [ "${-#*E}" != "$-" ]; then + set +E; + local EXIT_CODE; + IFS="${DEFAULT_IFS}" nvm "$@"; + EXIT_CODE="$?"; + set -E; + return "$EXIT_CODE"; + else + if [ "${IFS}" != "${DEFAULT_IFS}" ]; then + IFS="${DEFAULT_IFS}" nvm "$@"; + return "$?"; + fi; + fi; + fi; + fi; + local i; + for i in "$@"; + do + case $i in + --) + break + ;; + '-h' | 'help' | '--help') + NVM_NO_COLORS=""; + for j in "$@"; + do + if [ "${j}" = '--no-colors' ]; then + NVM_NO_COLORS="${j}"; + break; + fi; + done; + local NVM_IOJS_PREFIX; + NVM_IOJS_PREFIX="$(nvm_iojs_prefix)"; + local NVM_NODE_PREFIX; + NVM_NODE_PREFIX="$(nvm_node_prefix)"; + NVM_VERSION="$(nvm --version)"; + nvm_echo; + nvm_echo "Node Version Manager (v${NVM_VERSION})"; + nvm_echo; + nvm_echo 'Note: refers to any version-like string nvm understands. This includes:'; + nvm_echo ' - full or partial version numbers, starting with an optional "v" (0.10, v0.1.2, v1)'; + nvm_echo " - default (built-in) aliases: ${NVM_NODE_PREFIX}, stable, unstable, ${NVM_IOJS_PREFIX}, system"; + nvm_echo ' - custom aliases you define with `nvm alias foo`'; + nvm_echo; + nvm_echo ' Any options that produce colorized output should respect the `--no-colors` option.'; + nvm_echo; + nvm_echo 'Usage:'; + nvm_echo ' nvm --help Show this message'; + nvm_echo ' --no-colors Suppress colored output'; + nvm_echo ' nvm --version Print out the installed version of nvm'; + nvm_echo ' nvm install [] Download and install a . Uses .nvmrc if available and version is omitted.'; + nvm_echo ' The following optional arguments, if provided, must appear directly after `nvm install`:'; + nvm_echo ' -s Skip binary download, install from source only.'; + nvm_echo ' -b Skip source download, install from binary only.'; + nvm_echo ' --reinstall-packages-from= When installing, reinstall packages installed in '; + nvm_echo ' --lts When installing, only select from LTS (long-term support) versions'; + nvm_echo ' --lts= When installing, only select from versions for a specific LTS line'; + nvm_echo ' --skip-default-packages When installing, skip the default-packages file if it exists'; + nvm_echo ' --latest-npm After installing, attempt to upgrade to the latest working npm on the given node version'; + nvm_echo ' --no-progress Disable the progress bar on any downloads'; + nvm_echo ' --alias= After installing, set the alias specified to the version specified. (same as: nvm alias )'; + nvm_echo ' --default After installing, set default alias to the version specified. (same as: nvm alias default )'; + nvm_echo ' --save After installing, write the specified version to .nvmrc'; + nvm_echo ' nvm uninstall Uninstall a version'; + nvm_echo ' nvm uninstall --lts Uninstall using automatic LTS (long-term support) alias `lts/*`, if available.'; + nvm_echo ' nvm uninstall --lts= Uninstall using automatic alias for provided LTS line, if available.'; + nvm_echo ' nvm use [] Modify PATH to use . Uses .nvmrc if available and version is omitted.'; + nvm_echo ' The following optional arguments, if provided, must appear directly after `nvm use`:'; + nvm_echo ' --silent Silences stdout/stderr output'; + nvm_echo ' --lts Uses automatic LTS (long-term support) alias `lts/*`, if available.'; + nvm_echo ' --lts= Uses automatic alias for provided LTS line, if available.'; + nvm_echo ' --save Writes the specified version to .nvmrc.'; + nvm_echo ' nvm exec [] [] Run on . Uses .nvmrc if available and version is omitted.'; + nvm_echo ' The following optional arguments, if provided, must appear directly after `nvm exec`:'; + nvm_echo ' --silent Silences stdout/stderr output'; + nvm_echo ' --lts Uses automatic LTS (long-term support) alias `lts/*`, if available.'; + nvm_echo ' --lts= Uses automatic alias for provided LTS line, if available.'; + nvm_echo ' nvm run [] [] Run `node` on with as arguments. Uses .nvmrc if available and version is omitted.'; + nvm_echo ' The following optional arguments, if provided, must appear directly after `nvm run`:'; + nvm_echo ' --silent Silences stdout/stderr output'; + nvm_echo ' --lts Uses automatic LTS (long-term support) alias `lts/*`, if available.'; + nvm_echo ' --lts= Uses automatic alias for provided LTS line, if available.'; + nvm_echo ' nvm current Display currently activated version of Node'; + nvm_echo ' nvm ls [] List installed versions, matching a given if provided'; + nvm_echo ' --no-colors Suppress colored output'; + nvm_echo ' --no-alias Suppress `nvm alias` output'; + nvm_echo ' nvm ls-remote [] List remote versions available for install, matching a given if provided'; + nvm_echo ' --lts When listing, only show LTS (long-term support) versions'; + nvm_echo ' --lts= When listing, only show versions for a specific LTS line'; + nvm_echo ' --no-colors Suppress colored output'; + nvm_echo ' nvm version Resolve the given description to a single local version'; + nvm_echo ' nvm version-remote Resolve the given description to a single remote version'; + nvm_echo ' --lts When listing, only select from LTS (long-term support) versions'; + nvm_echo ' --lts= When listing, only select from versions for a specific LTS line'; + nvm_echo ' nvm deactivate Undo effects of `nvm` on current shell'; + nvm_echo ' --silent Silences stdout/stderr output'; + nvm_echo ' nvm alias [] Show all aliases beginning with '; + nvm_echo ' --no-colors Suppress colored output'; + nvm_echo ' nvm alias Set an alias named pointing to '; + nvm_echo ' nvm unalias Deletes the alias named '; + nvm_echo ' nvm install-latest-npm Attempt to upgrade to the latest working `npm` on the current node version'; + nvm_echo ' nvm reinstall-packages Reinstall global `npm` packages contained in to current version'; + nvm_echo ' nvm unload Unload `nvm` from shell'; + nvm_echo ' nvm which [current | ] Display path to installed node version. Uses .nvmrc if available and version is omitted.'; + nvm_echo ' --silent Silences stdout/stderr output when a version is omitted'; + nvm_echo ' nvm cache dir Display path to the cache directory for nvm'; + nvm_echo ' nvm cache clear Empty cache directory for nvm'; + nvm_echo ' nvm set-colors [] Set five text colors using format "yMeBg". Available when supported.'; + nvm_echo ' Initial colors are:'; + nvm_echo_with_colors " $(nvm_wrap_with_color_code 'b' 'b')$(nvm_wrap_with_color_code 'y' 'y')$(nvm_wrap_with_color_code 'g' 'g')$(nvm_wrap_with_color_code 'r' 'r')$(nvm_wrap_with_color_code 'e' 'e')"; + nvm_echo ' Color codes:'; + nvm_echo_with_colors " $(nvm_wrap_with_color_code 'r' 'r')/$(nvm_wrap_with_color_code 'R' 'R') = $(nvm_wrap_with_color_code 'r' 'red') / $(nvm_wrap_with_color_code 'R' 'bold red')"; + nvm_echo_with_colors " $(nvm_wrap_with_color_code 'g' 'g')/$(nvm_wrap_with_color_code 'G' 'G') = $(nvm_wrap_with_color_code 'g' 'green') / $(nvm_wrap_with_color_code 'G' 'bold green')"; + nvm_echo_with_colors " $(nvm_wrap_with_color_code 'b' 'b')/$(nvm_wrap_with_color_code 'B' 'B') = $(nvm_wrap_with_color_code 'b' 'blue') / $(nvm_wrap_with_color_code 'B' 'bold blue')"; + nvm_echo_with_colors " $(nvm_wrap_with_color_code 'c' 'c')/$(nvm_wrap_with_color_code 'C' 'C') = $(nvm_wrap_with_color_code 'c' 'cyan') / $(nvm_wrap_with_color_code 'C' 'bold cyan')"; + nvm_echo_with_colors " $(nvm_wrap_with_color_code 'm' 'm')/$(nvm_wrap_with_color_code 'M' 'M') = $(nvm_wrap_with_color_code 'm' 'magenta') / $(nvm_wrap_with_color_code 'M' 'bold magenta')"; + nvm_echo_with_colors " $(nvm_wrap_with_color_code 'y' 'y')/$(nvm_wrap_with_color_code 'Y' 'Y') = $(nvm_wrap_with_color_code 'y' 'yellow') / $(nvm_wrap_with_color_code 'Y' 'bold yellow')"; + nvm_echo_with_colors " $(nvm_wrap_with_color_code 'k' 'k')/$(nvm_wrap_with_color_code 'K' 'K') = $(nvm_wrap_with_color_code 'k' 'black') / $(nvm_wrap_with_color_code 'K' 'bold black')"; + nvm_echo_with_colors " $(nvm_wrap_with_color_code 'e' 'e')/$(nvm_wrap_with_color_code 'W' 'W') = $(nvm_wrap_with_color_code 'e' 'light grey') / $(nvm_wrap_with_color_code 'W' 'white')"; + nvm_echo 'Example:'; + nvm_echo ' nvm install 8.0.0 Install a specific version number'; + nvm_echo ' nvm use 8.0 Use the latest available 8.0.x release'; + nvm_echo ' nvm run 6.10.3 app.js Run app.js using node 6.10.3'; + nvm_echo ' nvm exec 4.8.3 node app.js Run `node app.js` with the PATH pointing to node 4.8.3'; + nvm_echo ' nvm alias default 8.1.0 Set default node version on a shell'; + nvm_echo ' nvm alias default node Always default to the latest available node version on a shell'; + nvm_echo; + nvm_echo ' nvm install node Install the latest available version'; + nvm_echo ' nvm use node Use the latest version'; + nvm_echo ' nvm install --lts Install the latest LTS version'; + nvm_echo ' nvm use --lts Use the latest LTS version'; + nvm_echo; + nvm_echo ' nvm set-colors cgYmW Set text colors to cyan, green, bold yellow, magenta, and white'; + nvm_echo; + nvm_echo 'Note:'; + nvm_echo ' to remove, delete, or uninstall nvm - just remove the `$NVM_DIR` folder (usually `~/.nvm`)'; + nvm_echo; + return 0 + ;; + esac; + done; + local COMMAND; + COMMAND="${1-}"; + shift; + local VERSION; + local ADDITIONAL_PARAMETERS; + case $COMMAND in + "cache") + case "${1-}" in + dir) + nvm_cache_dir + ;; + clear) + local DIR; + DIR="$(nvm_cache_dir)"; + if command rm -rf "${DIR}" && command mkdir -p "${DIR}"; then + nvm_echo 'nvm cache cleared.'; + else + nvm_err "Unable to clear nvm cache: ${DIR}"; + return 1; + fi + ;; + *) + nvm --help 1>&2; + return 127 + ;; + esac + ;; + "debug") + local OS_VERSION; + nvm_is_zsh && setopt local_options shwordsplit; + nvm_err "nvm --version: v$(nvm --version)"; + if [ -n "${TERM_PROGRAM-}" ]; then + nvm_err "\$TERM_PROGRAM: ${TERM_PROGRAM}"; + fi; + nvm_err "\$SHELL: ${SHELL}"; + nvm_err "\$SHLVL: ${SHLVL-}"; + nvm_err "whoami: '$(whoami)'"; + nvm_err "\${HOME}: ${HOME}"; + nvm_err "\${NVM_DIR}: '$(nvm_sanitize_path "${NVM_DIR}")'"; + nvm_err "\${PATH}: $(nvm_sanitize_path "${PATH}")"; + nvm_err "\$PREFIX: '$(nvm_sanitize_path "${PREFIX}")'"; + nvm_err "\${NPM_CONFIG_PREFIX}: '$(nvm_sanitize_path "${NPM_CONFIG_PREFIX}")'"; + nvm_err "\$NVM_NODEJS_ORG_MIRROR: '${NVM_NODEJS_ORG_MIRROR}'"; + nvm_err "\$NVM_IOJS_ORG_MIRROR: '${NVM_IOJS_ORG_MIRROR}'"; + nvm_err "shell version: '$(${SHELL} --version | command head -n 1)'"; + nvm_err "uname -a: '$(command uname -a | command awk '{$2=""; print}' | command xargs)'"; + nvm_err "checksum binary: '$(nvm_get_checksum_binary 2> /dev/null)'"; + if [ "$(nvm_get_os)" = "darwin" ] && nvm_has sw_vers; then + OS_VERSION="$(sw_vers | command awk '{print $2}' | command xargs)"; + else + if [ -r "/etc/issue" ]; then + OS_VERSION="$(command head -n 1 /etc/issue | command sed 's/\\.//g')"; + if [ -z "${OS_VERSION}" ] && [ -r "/etc/os-release" ]; then + OS_VERSION="$(. /etc/os-release && echo "${NAME}" "${VERSION}")"; + fi; + fi; + fi; + if [ -n "${OS_VERSION}" ]; then + nvm_err "OS version: ${OS_VERSION}"; + fi; + if nvm_has "awk"; then + nvm_err "awk: $(nvm_command_info awk), $({ command awk --version 2> /dev/null || command awk -W version; } | command head -n 1)"; + else + nvm_err "awk: not found"; + fi; + if nvm_has "curl"; then + nvm_err "curl: $(nvm_command_info curl), $(command curl -V | command head -n 1)"; + else + nvm_err "curl: not found"; + fi; + if nvm_has "wget"; then + nvm_err "wget: $(nvm_command_info wget), $(command wget -V | command head -n 1)"; + else + nvm_err "wget: not found"; + fi; + local TEST_TOOLS ADD_TEST_TOOLS; + TEST_TOOLS="git grep"; + ADD_TEST_TOOLS="sed cut basename rm mkdir xargs"; + if [ "darwin" != "$(nvm_get_os)" ] && [ "freebsd" != "$(nvm_get_os)" ]; then + TEST_TOOLS="${TEST_TOOLS} ${ADD_TEST_TOOLS}"; + else + for tool in ${ADD_TEST_TOOLS}; + do + if nvm_has "${tool}"; then + nvm_err "${tool}: $(nvm_command_info "${tool}")"; + else + nvm_err "${tool}: not found"; + fi; + done; + fi; + for tool in ${TEST_TOOLS}; + do + local NVM_TOOL_VERSION; + if nvm_has "${tool}"; then + if command ls -l "$(nvm_command_info "${tool}" | command awk '{print $1}')" | command grep -q busybox; then + NVM_TOOL_VERSION="$(command "${tool}" --help 2>&1 | command head -n 1)"; + else + NVM_TOOL_VERSION="$(command "${tool}" --version 2>&1 | command head -n 1)"; + fi; + nvm_err "${tool}: $(nvm_command_info "${tool}"), ${NVM_TOOL_VERSION}"; + else + nvm_err "${tool}: not found"; + fi; + unset NVM_TOOL_VERSION; + done; + unset TEST_TOOLS ADD_TEST_TOOLS; + local NVM_DEBUG_OUTPUT; + for NVM_DEBUG_COMMAND in 'nvm current' 'which node' 'which iojs' 'which npm' 'npm config get prefix' 'npm root -g'; + do + NVM_DEBUG_OUTPUT="$(${NVM_DEBUG_COMMAND} 2>&1)"; + nvm_err "${NVM_DEBUG_COMMAND}: $(nvm_sanitize_path "${NVM_DEBUG_OUTPUT}")"; + done; + return 42 + ;; + "install" | "i") + local version_not_provided; + version_not_provided=0; + local NVM_OS; + NVM_OS="$(nvm_get_os)"; + if ! nvm_has "curl" && ! nvm_has "wget"; then + nvm_err 'nvm needs curl or wget to proceed.'; + return 1; + fi; + if [ $# -lt 1 ]; then + version_not_provided=1; + fi; + local nobinary; + local nosource; + local noprogress; + nobinary=0; + noprogress=0; + nosource=0; + local LTS; + local ALIAS; + local NVM_UPGRADE_NPM; + NVM_UPGRADE_NPM=0; + local NVM_WRITE_TO_NVMRC; + NVM_WRITE_TO_NVMRC=0; + local PROVIDED_REINSTALL_PACKAGES_FROM; + local REINSTALL_PACKAGES_FROM; + local SKIP_DEFAULT_PACKAGES; + while [ $# -ne 0 ]; do + case "$1" in + ---*) + nvm_err 'arguments with `---` are not supported - this is likely a typo'; + return 55 + ;; + -s) + shift; + nobinary=1; + if [ $nosource -eq 1 ]; then + nvm err '-s and -b cannot be set together since they would skip install from both binary and source'; + return 6; + fi + ;; + -b) + shift; + nosource=1; + if [ $nobinary -eq 1 ]; then + nvm err '-s and -b cannot be set together since they would skip install from both binary and source'; + return 6; + fi + ;; + -j) + shift; + nvm_get_make_jobs "$1"; + shift + ;; + --no-progress) + noprogress=1; + shift + ;; + --lts) + LTS='*'; + shift + ;; + --lts=*) + LTS="${1##--lts=}"; + shift + ;; + --latest-npm) + NVM_UPGRADE_NPM=1; + shift + ;; + --default) + if [ -n "${ALIAS-}" ]; then + nvm_err '--default and --alias are mutually exclusive, and may not be provided more than once'; + return 6; + fi; + ALIAS='default'; + shift + ;; + --alias=*) + if [ -n "${ALIAS-}" ]; then + nvm_err '--default and --alias are mutually exclusive, and may not be provided more than once'; + return 6; + fi; + ALIAS="${1##--alias=}"; + shift + ;; + --reinstall-packages-from=*) + if [ -n "${PROVIDED_REINSTALL_PACKAGES_FROM-}" ]; then + nvm_err '--reinstall-packages-from may not be provided more than once'; + return 6; + fi; + PROVIDED_REINSTALL_PACKAGES_FROM="$(nvm_echo "$1" | command cut -c 27-)"; + if [ -z "${PROVIDED_REINSTALL_PACKAGES_FROM}" ]; then + nvm_err 'If --reinstall-packages-from is provided, it must point to an installed version of node.'; + return 6; + fi; + REINSTALL_PACKAGES_FROM="$(nvm_version "${PROVIDED_REINSTALL_PACKAGES_FROM}")" || :; + shift + ;; + --copy-packages-from=*) + if [ -n "${PROVIDED_REINSTALL_PACKAGES_FROM-}" ]; then + nvm_err '--reinstall-packages-from may not be provided more than once, or combined with `--copy-packages-from`'; + return 6; + fi; + PROVIDED_REINSTALL_PACKAGES_FROM="$(nvm_echo "$1" | command cut -c 22-)"; + if [ -z "${PROVIDED_REINSTALL_PACKAGES_FROM}" ]; then + nvm_err 'If --copy-packages-from is provided, it must point to an installed version of node.'; + return 6; + fi; + REINSTALL_PACKAGES_FROM="$(nvm_version "${PROVIDED_REINSTALL_PACKAGES_FROM}")" || :; + shift + ;; + --reinstall-packages-from | --copy-packages-from) + nvm_err "If ${1} is provided, it must point to an installed version of node using \`=\`."; + return 6 + ;; + --skip-default-packages) + SKIP_DEFAULT_PACKAGES=true; + shift + ;; + --save | -w) + if [ $NVM_WRITE_TO_NVMRC -eq 1 ]; then + nvm_err '--save and -w may only be provided once'; + return 6; + fi; + NVM_WRITE_TO_NVMRC=1; + shift + ;; + *) + break + ;; + esac; + done; + local provided_version; + provided_version="${1-}"; + if [ -z "${provided_version}" ]; then + if [ "_${LTS-}" = '_*' ]; then + nvm_echo 'Installing latest LTS version.'; + if [ $# -gt 0 ]; then + shift; + fi; + else + if [ "_${LTS-}" != '_' ]; then + nvm_echo "Installing with latest version of LTS line: ${LTS}"; + if [ $# -gt 0 ]; then + shift; + fi; + else + nvm_rc_version; + if [ $version_not_provided -eq 1 ] && [ -z "${NVM_RC_VERSION}" ]; then + unset NVM_RC_VERSION; + nvm --help 1>&2; + return 127; + fi; + provided_version="${NVM_RC_VERSION}"; + unset NVM_RC_VERSION; + fi; + fi; + else + if [ $# -gt 0 ]; then + shift; + fi; + fi; + case "${provided_version}" in + 'lts/*') + LTS='*'; + provided_version='' + ;; + lts/*) + LTS="${provided_version##lts/}"; + provided_version='' + ;; + esac; + local EXIT_CODE; + VERSION="$(NVM_VERSION_ONLY=true NVM_LTS="${LTS-}" nvm_remote_version "${provided_version}")"; + EXIT_CODE="$?"; + if [ "${VERSION}" = 'N/A' ] || [ $EXIT_CODE -ne 0 ]; then + local LTS_MSG; + local REMOTE_CMD; + if [ "${LTS-}" = '*' ]; then + LTS_MSG='(with LTS filter) '; + REMOTE_CMD='nvm ls-remote --lts'; + else + if [ -n "${LTS-}" ]; then + LTS_MSG="(with LTS filter '${LTS}') "; + REMOTE_CMD="nvm ls-remote --lts=${LTS}"; + if [ -z "${provided_version}" ]; then + nvm_err "Version with LTS filter '${LTS}' not found - try \`${REMOTE_CMD}\` to browse available versions."; + return 3; + fi; + else + REMOTE_CMD='nvm ls-remote'; + fi; + fi; + nvm_err "Version '${provided_version}' ${LTS_MSG-}not found - try \`${REMOTE_CMD}\` to browse available versions."; + return 3; + fi; + ADDITIONAL_PARAMETERS=''; + while [ $# -ne 0 ]; do + case "$1" in + --reinstall-packages-from=*) + if [ -n "${PROVIDED_REINSTALL_PACKAGES_FROM-}" ]; then + nvm_err '--reinstall-packages-from may not be provided more than once'; + return 6; + fi; + PROVIDED_REINSTALL_PACKAGES_FROM="$(nvm_echo "$1" | command cut -c 27-)"; + if [ -z "${PROVIDED_REINSTALL_PACKAGES_FROM}" ]; then + nvm_err 'If --reinstall-packages-from is provided, it must point to an installed version of node.'; + return 6; + fi; + REINSTALL_PACKAGES_FROM="$(nvm_version "${PROVIDED_REINSTALL_PACKAGES_FROM}")" || : + ;; + --copy-packages-from=*) + if [ -n "${PROVIDED_REINSTALL_PACKAGES_FROM-}" ]; then + nvm_err '--reinstall-packages-from may not be provided more than once, or combined with `--copy-packages-from`'; + return 6; + fi; + PROVIDED_REINSTALL_PACKAGES_FROM="$(nvm_echo "$1" | command cut -c 22-)"; + if [ -z "${PROVIDED_REINSTALL_PACKAGES_FROM}" ]; then + nvm_err 'If --copy-packages-from is provided, it must point to an installed version of node.'; + return 6; + fi; + REINSTALL_PACKAGES_FROM="$(nvm_version "${PROVIDED_REINSTALL_PACKAGES_FROM}")" || : + ;; + --reinstall-packages-from | --copy-packages-from) + nvm_err "If ${1} is provided, it must point to an installed version of node using \`=\`."; + return 6 + ;; + --skip-default-packages) + SKIP_DEFAULT_PACKAGES=true + ;; + *) + ADDITIONAL_PARAMETERS="${ADDITIONAL_PARAMETERS} $1" + ;; + esac; + shift; + done; + if [ -n "${PROVIDED_REINSTALL_PACKAGES_FROM-}" ] && [ "$(nvm_ensure_version_prefix "${PROVIDED_REINSTALL_PACKAGES_FROM}")" = "${VERSION}" ]; then + nvm_err "You can't reinstall global packages from the same version of node you're installing."; + return 4; + else + if [ "${REINSTALL_PACKAGES_FROM-}" = 'N/A' ]; then + nvm_err "If --reinstall-packages-from is provided, it must point to an installed version of node."; + return 5; + fi; + fi; + local FLAVOR; + if nvm_is_iojs_version "${VERSION}"; then + FLAVOR="$(nvm_iojs_prefix)"; + else + FLAVOR="$(nvm_node_prefix)"; + fi; + EXIT_CODE=0; + if nvm_is_version_installed "${VERSION}"; then + nvm_err "${VERSION} is already installed."; + nvm use "${VERSION}"; + EXIT_CODE=$?; + if [ $EXIT_CODE -eq 0 ]; then + if [ "${NVM_UPGRADE_NPM}" = 1 ]; then + nvm install-latest-npm; + EXIT_CODE=$?; + fi; + if [ $EXIT_CODE -ne 0 ] && [ -z "${SKIP_DEFAULT_PACKAGES-}" ]; then + nvm_install_default_packages; + fi; + if [ $EXIT_CODE -ne 0 ] && [ -n "${REINSTALL_PACKAGES_FROM-}" ] && [ "_${REINSTALL_PACKAGES_FROM}" != "_N/A" ]; then + nvm reinstall-packages "${REINSTALL_PACKAGES_FROM}"; + EXIT_CODE=$?; + fi; + fi; + if [ -n "${LTS-}" ]; then + LTS="$(echo "${LTS}" | tr '[:upper:]' '[:lower:]')"; + nvm_ensure_default_set "lts/${LTS}"; + else + nvm_ensure_default_set "${provided_version}"; + fi; + if [ $NVM_WRITE_TO_NVMRC -eq 1 ]; then + nvm_write_nvmrc "${VERSION}"; + EXIT_CODE=$?; + fi; + if [ $EXIT_CODE -ne 0 ] && [ -n "${ALIAS-}" ]; then + nvm alias "${ALIAS}" "${provided_version}"; + EXIT_CODE=$?; + fi; + return $EXIT_CODE; + fi; + if [ -n "${NVM_INSTALL_THIRD_PARTY_HOOK-}" ]; then + nvm_err '** $NVM_INSTALL_THIRD_PARTY_HOOK env var set; dispatching to third-party installation method **'; + local NVM_METHOD_PREFERENCE; + NVM_METHOD_PREFERENCE='binary'; + if [ $nobinary -eq 1 ]; then + NVM_METHOD_PREFERENCE='source'; + fi; + local VERSION_PATH; + VERSION_PATH="$(nvm_version_path "${VERSION}")"; + "${NVM_INSTALL_THIRD_PARTY_HOOK}" "${VERSION}" "${FLAVOR}" std "${NVM_METHOD_PREFERENCE}" "${VERSION_PATH}" || { + EXIT_CODE=$?; + nvm_err '*** Third-party $NVM_INSTALL_THIRD_PARTY_HOOK env var failed to install! ***'; + return $EXIT_CODE + }; + if ! nvm_is_version_installed "${VERSION}"; then + nvm_err '*** Third-party $NVM_INSTALL_THIRD_PARTY_HOOK env var claimed to succeed, but failed to install! ***'; + return 33; + fi; + EXIT_CODE=0; + else + if [ "_${NVM_OS}" = "_freebsd" ]; then + nobinary=1; + nvm_err "Currently, there is no binary for FreeBSD"; + else + if [ "_$NVM_OS" = "_openbsd" ]; then + nobinary=1; + nvm_err "Currently, there is no binary for OpenBSD"; + else + if [ "_${NVM_OS}" = "_sunos" ]; then + if ! nvm_has_solaris_binary "${VERSION}"; then + nobinary=1; + nvm_err "Currently, there is no binary of version ${VERSION} for SunOS"; + fi; + fi; + fi; + fi; + if [ $nobinary -ne 1 ] && nvm_binary_available "${VERSION}"; then + NVM_NO_PROGRESS="${NVM_NO_PROGRESS:-${noprogress}}" nvm_install_binary "${FLAVOR}" std "${VERSION}" "${nosource}"; + EXIT_CODE=$?; + else + EXIT_CODE=-1; + if [ $nosource -eq 1 ]; then + nvm_err "Binary download is not available for ${VERSION}"; + EXIT_CODE=3; + fi; + fi; + if [ $EXIT_CODE -ne 0 ] && [ $nosource -ne 1 ]; then + if [ -z "${NVM_MAKE_JOBS-}" ]; then + nvm_get_make_jobs; + fi; + if [ "_${NVM_OS}" = "_win" ]; then + nvm_err 'Installing from source on non-WSL Windows is not supported'; + EXIT_CODE=87; + else + NVM_NO_PROGRESS="${NVM_NO_PROGRESS:-${noprogress}}" nvm_install_source "${FLAVOR}" std "${VERSION}" "${NVM_MAKE_JOBS}" "${ADDITIONAL_PARAMETERS}"; + EXIT_CODE=$?; + fi; + fi; + fi; + if [ $EXIT_CODE -eq 0 ]; then + if nvm_use_if_needed "${VERSION}" && nvm_install_npm_if_needed "${VERSION}"; then + if [ -n "${LTS-}" ]; then + nvm_ensure_default_set "lts/${LTS}"; + else + nvm_ensure_default_set "${provided_version}"; + fi; + if [ "${NVM_UPGRADE_NPM}" = 1 ]; then + nvm install-latest-npm; + EXIT_CODE=$?; + fi; + if [ $EXIT_CODE -eq 0 ] && [ -z "${SKIP_DEFAULT_PACKAGES-}" ]; then + nvm_install_default_packages; + fi; + if [ $EXIT_CODE -eq 0 ] && [ -n "${REINSTALL_PACKAGES_FROM-}" ] && [ "_${REINSTALL_PACKAGES_FROM}" != "_N/A" ]; then + nvm reinstall-packages "${REINSTALL_PACKAGES_FROM}"; + EXIT_CODE=$?; + fi; + else + EXIT_CODE=$?; + fi; + fi; + return $EXIT_CODE + ;; + "uninstall") + if [ $# -ne 1 ]; then + nvm --help 1>&2; + return 127; + fi; + local PATTERN; + PATTERN="${1-}"; + case "${PATTERN-}" in + --) + + ;; + --lts | 'lts/*') + VERSION="$(nvm_match_version "lts/*")" + ;; + lts/*) + VERSION="$(nvm_match_version "lts/${PATTERN##lts/}")" + ;; + --lts=*) + VERSION="$(nvm_match_version "lts/${PATTERN##--lts=}")" + ;; + *) + VERSION="$(nvm_version "${PATTERN}")" + ;; + esac; + if [ "_${VERSION}" = "_$(nvm_ls_current)" ]; then + if nvm_is_iojs_version "${VERSION}"; then + nvm_err "nvm: Cannot uninstall currently-active io.js version, ${VERSION} (inferred from ${PATTERN})."; + else + nvm_err "nvm: Cannot uninstall currently-active node version, ${VERSION} (inferred from ${PATTERN})."; + fi; + return 1; + fi; + if ! nvm_is_version_installed "${VERSION}"; then + nvm_err "${VERSION} version is not installed..."; + return; + fi; + local SLUG_BINARY; + local SLUG_SOURCE; + if nvm_is_iojs_version "${VERSION}"; then + SLUG_BINARY="$(nvm_get_download_slug iojs binary std "${VERSION}")"; + SLUG_SOURCE="$(nvm_get_download_slug iojs source std "${VERSION}")"; + else + SLUG_BINARY="$(nvm_get_download_slug node binary std "${VERSION}")"; + SLUG_SOURCE="$(nvm_get_download_slug node source std "${VERSION}")"; + fi; + local NVM_SUCCESS_MSG; + if nvm_is_iojs_version "${VERSION}"; then + NVM_SUCCESS_MSG="Uninstalled io.js $(nvm_strip_iojs_prefix "${VERSION}")"; + else + NVM_SUCCESS_MSG="Uninstalled node ${VERSION}"; + fi; + local VERSION_PATH; + VERSION_PATH="$(nvm_version_path "${VERSION}")"; + if ! nvm_check_file_permissions "${VERSION_PATH}"; then + nvm_err 'Cannot uninstall, incorrect permissions on installation folder.'; + nvm_err 'This is usually caused by running `npm install -g` as root. Run the following commands as root to fix the permissions and then try again.'; + nvm_err; + nvm_err " chown -R $(whoami) \"$(nvm_sanitize_path "${VERSION_PATH}")\""; + nvm_err " chmod -R u+w \"$(nvm_sanitize_path "${VERSION_PATH}")\""; + return 1; + fi; + local CACHE_DIR; + CACHE_DIR="$(nvm_cache_dir)"; + command rm -rf "${CACHE_DIR}/bin/${SLUG_BINARY}/files" "${CACHE_DIR}/src/${SLUG_SOURCE}/files" "${VERSION_PATH}" 2> /dev/null; + nvm_echo "${NVM_SUCCESS_MSG}"; + for ALIAS in $(nvm_grep -l "${VERSION}" "$(nvm_alias_path)/*" 2> /dev/null); + do + nvm unalias "$(command basename "${ALIAS}")"; + done + ;; + "deactivate") + local NVM_SILENT; + while [ $# -ne 0 ]; do + case "${1}" in + --silent) + NVM_SILENT=1 + ;; + --) + + ;; + esac; + shift; + done; + local NEWPATH; + NEWPATH="$(nvm_strip_path "${PATH}" "/bin")"; + if [ "_${PATH}" = "_${NEWPATH}" ]; then + if [ "${NVM_SILENT:-0}" -ne 1 ]; then + nvm_err "Could not find ${NVM_DIR}/*/bin in \${PATH}"; + fi; + else + export PATH="${NEWPATH}"; + \hash -r; + if [ "${NVM_SILENT:-0}" -ne 1 ]; then + nvm_echo "${NVM_DIR}/*/bin removed from \${PATH}"; + fi; + fi; + if [ -n "${MANPATH-}" ]; then + NEWPATH="$(nvm_strip_path "${MANPATH}" "/share/man")"; + if [ "_${MANPATH}" = "_${NEWPATH}" ]; then + if [ "${NVM_SILENT:-0}" -ne 1 ]; then + nvm_err "Could not find ${NVM_DIR}/*/share/man in \${MANPATH}"; + fi; + else + export MANPATH="${NEWPATH}"; + if [ "${NVM_SILENT:-0}" -ne 1 ]; then + nvm_echo "${NVM_DIR}/*/share/man removed from \${MANPATH}"; + fi; + fi; + fi; + if [ -n "${NODE_PATH-}" ]; then + NEWPATH="$(nvm_strip_path "${NODE_PATH}" "/lib/node_modules")"; + if [ "_${NODE_PATH}" != "_${NEWPATH}" ]; then + export NODE_PATH="${NEWPATH}"; + if [ "${NVM_SILENT:-0}" -ne 1 ]; then + nvm_echo "${NVM_DIR}/*/lib/node_modules removed from \${NODE_PATH}"; + fi; + fi; + fi; + unset NVM_BIN; + unset NVM_INC + ;; + "use") + local PROVIDED_VERSION; + local NVM_SILENT; + local NVM_SILENT_ARG; + local NVM_DELETE_PREFIX; + NVM_DELETE_PREFIX=0; + local NVM_LTS; + local IS_VERSION_FROM_NVMRC; + IS_VERSION_FROM_NVMRC=0; + local NVM_WRITE_TO_NVMRC; + NVM_WRITE_TO_NVMRC=0; + while [ $# -ne 0 ]; do + case "$1" in + --silent) + NVM_SILENT=1; + NVM_SILENT_ARG='--silent' + ;; + --delete-prefix) + NVM_DELETE_PREFIX=1 + ;; + --) + + ;; + --lts) + NVM_LTS='*' + ;; + --lts=*) + NVM_LTS="${1##--lts=}" + ;; + --save | -w) + if [ $NVM_WRITE_TO_NVMRC -eq 1 ]; then + nvm_err '--save and -w may only be provided once'; + return 6; + fi; + NVM_WRITE_TO_NVMRC=1 + ;; + --*) + + ;; + *) + if [ -n "${1-}" ]; then + PROVIDED_VERSION="$1"; + fi + ;; + esac; + shift; + done; + if [ -n "${NVM_LTS-}" ]; then + VERSION="$(nvm_match_version "lts/${NVM_LTS:-*}")"; + else + if [ -z "${PROVIDED_VERSION-}" ]; then + NVM_SILENT="${NVM_SILENT:-0}" nvm_rc_version; + if [ -n "${NVM_RC_VERSION-}" ]; then + PROVIDED_VERSION="${NVM_RC_VERSION}"; + IS_VERSION_FROM_NVMRC=1; + VERSION="$(nvm_version "${PROVIDED_VERSION}")"; + fi; + unset NVM_RC_VERSION; + if [ -z "${VERSION}" ]; then + nvm_err 'Please see `nvm --help` or https://github.com/nvm-sh/nvm#nvmrc for more information.'; + return 127; + fi; + else + VERSION="$(nvm_match_version "${PROVIDED_VERSION}")"; + fi; + fi; + if [ -z "${VERSION}" ]; then + nvm --help 1>&2; + return 127; + fi; + if [ $NVM_WRITE_TO_NVMRC -eq 1 ]; then + nvm_write_nvmrc "${VERSION}"; + fi; + if [ "_${VERSION}" = '_system' ]; then + if nvm_has_system_node && nvm deactivate "${NVM_SILENT_ARG-}" > /dev/null 2>&1; then + if [ "${NVM_SILENT:-0}" -ne 1 ]; then + nvm_echo "Now using system version of node: $(node -v 2> /dev/null)$(nvm_print_npm_version)"; + fi; + return; + else + if nvm_has_system_iojs && nvm deactivate "${NVM_SILENT_ARG-}" > /dev/null 2>&1; then + if [ "${NVM_SILENT:-0}" -ne 1 ]; then + nvm_echo "Now using system version of io.js: $(iojs --version 2> /dev/null)$(nvm_print_npm_version)"; + fi; + return; + else + if [ "${NVM_SILENT:-0}" -ne 1 ]; then + nvm_err 'System version of node not found.'; + fi; + fi; + fi; + return 127; + else + if [ "_${VERSION}" = '_∞' ]; then + if [ "${NVM_SILENT:-0}" -ne 1 ]; then + nvm_err "The alias \"${PROVIDED_VERSION}\" leads to an infinite loop. Aborting."; + fi; + return 8; + fi; + fi; + if [ "${VERSION}" = 'N/A' ]; then + if [ "${NVM_SILENT:-0}" -ne 1 ]; then + nvm_ensure_version_installed "${PROVIDED_VERSION}" "${IS_VERSION_FROM_NVMRC}"; + fi; + return 3; + else + if ! nvm_ensure_version_installed "${VERSION}" "${IS_VERSION_FROM_NVMRC}"; then + return $?; + fi; + fi; + local NVM_VERSION_DIR; + NVM_VERSION_DIR="$(nvm_version_path "${VERSION}")"; + PATH="$(nvm_change_path "${PATH}" "/bin" "${NVM_VERSION_DIR}")"; + if nvm_has manpath; then + if [ -z "${MANPATH-}" ]; then + local MANPATH; + MANPATH=$(manpath); + fi; + MANPATH="$(nvm_change_path "${MANPATH}" "/share/man" "${NVM_VERSION_DIR}")"; + export MANPATH; + fi; + export PATH; + \hash -r; + export NVM_BIN="${NVM_VERSION_DIR}/bin"; + export NVM_INC="${NVM_VERSION_DIR}/include/node"; + if [ "${NVM_SYMLINK_CURRENT-}" = true ]; then + command rm -f "${NVM_DIR}/current" && ln -s "${NVM_VERSION_DIR}" "${NVM_DIR}/current"; + fi; + local NVM_USE_OUTPUT; + NVM_USE_OUTPUT=''; + if [ "${NVM_SILENT:-0}" -ne 1 ]; then + if nvm_is_iojs_version "${VERSION}"; then + NVM_USE_OUTPUT="Now using io.js $(nvm_strip_iojs_prefix "${VERSION}")$(nvm_print_npm_version)"; + else + NVM_USE_OUTPUT="Now using node ${VERSION}$(nvm_print_npm_version)"; + fi; + fi; + if [ "_${VERSION}" != "_system" ]; then + local NVM_USE_CMD; + NVM_USE_CMD="nvm use --delete-prefix"; + if [ -n "${PROVIDED_VERSION}" ]; then + NVM_USE_CMD="${NVM_USE_CMD} ${VERSION}"; + fi; + if [ "${NVM_SILENT:-0}" -eq 1 ]; then + NVM_USE_CMD="${NVM_USE_CMD} --silent"; + fi; + if ! nvm_die_on_prefix "${NVM_DELETE_PREFIX}" "${NVM_USE_CMD}" "${NVM_VERSION_DIR}"; then + return 11; + fi; + fi; + if [ -n "${NVM_USE_OUTPUT-}" ] && [ "${NVM_SILENT:-0}" -ne 1 ]; then + nvm_echo "${NVM_USE_OUTPUT}"; + fi + ;; + "run") + local provided_version; + local has_checked_nvmrc; + has_checked_nvmrc=0; + local IS_VERSION_FROM_NVMRC; + IS_VERSION_FROM_NVMRC=0; + local NVM_SILENT; + local NVM_SILENT_ARG; + local NVM_LTS; + while [ $# -gt 0 ]; do + case "$1" in + --silent) + NVM_SILENT=1; + NVM_SILENT_ARG='--silent'; + shift + ;; + --lts) + NVM_LTS='*'; + shift + ;; + --lts=*) + NVM_LTS="${1##--lts=}"; + shift + ;; + *) + if [ -n "$1" ]; then + break; + else + shift; + fi + ;; + esac; + done; + if [ $# -lt 1 ] && [ -z "${NVM_LTS-}" ]; then + NVM_SILENT="${NVM_SILENT:-0}" nvm_rc_version && has_checked_nvmrc=1; + if [ -n "${NVM_RC_VERSION-}" ]; then + VERSION="$(nvm_version "${NVM_RC_VERSION-}")" || :; + fi; + unset NVM_RC_VERSION; + if [ "${VERSION:-N/A}" = 'N/A' ]; then + nvm --help 1>&2; + return 127; + fi; + fi; + if [ -z "${NVM_LTS-}" ]; then + provided_version="$1"; + if [ -n "${provided_version}" ]; then + VERSION="$(nvm_version "${provided_version}")" || :; + if [ "_${VERSION:-N/A}" = '_N/A' ] && ! nvm_is_valid_version "${provided_version}"; then + provided_version=''; + if [ $has_checked_nvmrc -ne 1 ]; then + NVM_SILENT="${NVM_SILENT:-0}" nvm_rc_version && has_checked_nvmrc=1; + fi; + provided_version="${NVM_RC_VERSION}"; + IS_VERSION_FROM_NVMRC=1; + VERSION="$(nvm_version "${NVM_RC_VERSION}")" || :; + unset NVM_RC_VERSION; + else + shift; + fi; + fi; + fi; + local NVM_IOJS; + if nvm_is_iojs_version "${VERSION}"; then + NVM_IOJS=true; + fi; + local EXIT_CODE; + nvm_is_zsh && setopt local_options shwordsplit; + local LTS_ARG; + if [ -n "${NVM_LTS-}" ]; then + LTS_ARG="--lts=${NVM_LTS-}"; + VERSION=''; + fi; + if [ "_${VERSION}" = "_N/A" ]; then + nvm_ensure_version_installed "${provided_version}" "${IS_VERSION_FROM_NVMRC}"; + else + if [ "${NVM_IOJS}" = true ]; then + nvm exec "${NVM_SILENT_ARG-}" "${LTS_ARG-}" "${VERSION}" iojs "$@"; + else + nvm exec "${NVM_SILENT_ARG-}" "${LTS_ARG-}" "${VERSION}" node "$@"; + fi; + fi; + EXIT_CODE="$?"; + return $EXIT_CODE + ;; + "exec") + local NVM_SILENT; + local NVM_LTS; + while [ $# -gt 0 ]; do + case "$1" in + --silent) + NVM_SILENT=1; + shift + ;; + --lts) + NVM_LTS='*'; + shift + ;; + --lts=*) + NVM_LTS="${1##--lts=}"; + shift + ;; + --) + break + ;; + --*) + nvm_err "Unsupported option \"$1\"."; + return 55 + ;; + *) + if [ -n "$1" ]; then + break; + else + shift; + fi + ;; + esac; + done; + local provided_version; + provided_version="$1"; + if [ "${NVM_LTS-}" != '' ]; then + provided_version="lts/${NVM_LTS:-*}"; + VERSION="${provided_version}"; + else + if [ -n "${provided_version}" ]; then + VERSION="$(nvm_version "${provided_version}")" || :; + if [ "_${VERSION}" = '_N/A' ] && ! nvm_is_valid_version "${provided_version}"; then + NVM_SILENT="${NVM_SILENT:-0}" nvm_rc_version && has_checked_nvmrc=1; + provided_version="${NVM_RC_VERSION}"; + unset NVM_RC_VERSION; + VERSION="$(nvm_version "${provided_version}")" || :; + else + shift; + fi; + fi; + fi; + nvm_ensure_version_installed "${provided_version}"; + EXIT_CODE=$?; + if [ "${EXIT_CODE}" != "0" ]; then + return $EXIT_CODE; + fi; + if [ "${NVM_SILENT:-0}" -ne 1 ]; then + if [ "${NVM_LTS-}" = '*' ]; then + nvm_echo "Running node latest LTS -> $(nvm_version "${VERSION}")$(nvm use --silent "${VERSION}" && nvm_print_npm_version)"; + else + if [ -n "${NVM_LTS-}" ]; then + nvm_echo "Running node LTS \"${NVM_LTS-}\" -> $(nvm_version "${VERSION}")$(nvm use --silent "${VERSION}" && nvm_print_npm_version)"; + else + if nvm_is_iojs_version "${VERSION}"; then + nvm_echo "Running io.js $(nvm_strip_iojs_prefix "${VERSION}")$(nvm use --silent "${VERSION}" && nvm_print_npm_version)"; + else + nvm_echo "Running node ${VERSION}$(nvm use --silent "${VERSION}" && nvm_print_npm_version)"; + fi; + fi; + fi; + fi; + NODE_VERSION="${VERSION}" "${NVM_DIR}/nvm-exec" "$@" + ;; + "ls" | "list") + local PATTERN; + local NVM_NO_COLORS; + local NVM_NO_ALIAS; + while [ $# -gt 0 ]; do + case "${1}" in + --) + + ;; + --no-colors) + NVM_NO_COLORS="${1}" + ;; + --no-alias) + NVM_NO_ALIAS="${1}" + ;; + --*) + nvm_err "Unsupported option \"${1}\"."; + return 55 + ;; + *) + PATTERN="${PATTERN:-$1}" + ;; + esac; + shift; + done; + if [ -n "${PATTERN-}" ] && [ -n "${NVM_NO_ALIAS-}" ]; then + nvm_err '`--no-alias` is not supported when a pattern is provided.'; + return 55; + fi; + local NVM_LS_OUTPUT; + local NVM_LS_EXIT_CODE; + NVM_LS_OUTPUT=$(nvm_ls "${PATTERN-}"); + NVM_LS_EXIT_CODE=$?; + NVM_NO_COLORS="${NVM_NO_COLORS-}" nvm_print_versions "${NVM_LS_OUTPUT}"; + if [ -z "${NVM_NO_ALIAS-}" ] && [ -z "${PATTERN-}" ]; then + if [ -n "${NVM_NO_COLORS-}" ]; then + nvm alias --no-colors; + else + nvm alias; + fi; + fi; + return $NVM_LS_EXIT_CODE + ;; + "ls-remote" | "list-remote") + local NVM_LTS; + local PATTERN; + local NVM_NO_COLORS; + while [ $# -gt 0 ]; do + case "${1-}" in + --) + + ;; + --lts) + NVM_LTS='*' + ;; + --lts=*) + NVM_LTS="${1##--lts=}" + ;; + --no-colors) + NVM_NO_COLORS="${1}" + ;; + --*) + nvm_err "Unsupported option \"${1}\"."; + return 55 + ;; + *) + if [ -z "${PATTERN-}" ]; then + PATTERN="${1-}"; + if [ -z "${NVM_LTS-}" ]; then + case "${PATTERN}" in + 'lts/*') + NVM_LTS='*'; + PATTERN='' + ;; + lts/*) + NVM_LTS="${PATTERN##lts/}"; + PATTERN='' + ;; + esac; + fi; + fi + ;; + esac; + shift; + done; + local NVM_OUTPUT; + local EXIT_CODE; + NVM_OUTPUT="$(NVM_LTS="${NVM_LTS-}" nvm_remote_versions "${PATTERN}" && :)"; + EXIT_CODE=$?; + if [ -n "${NVM_OUTPUT}" ]; then + NVM_NO_COLORS="${NVM_NO_COLORS-}" nvm_print_versions "${NVM_OUTPUT}"; + return $EXIT_CODE; + fi; + NVM_NO_COLORS="${NVM_NO_COLORS-}" nvm_print_versions "N/A"; + return 3 + ;; + "current") + nvm_version current + ;; + "which") + local NVM_SILENT; + local provided_version; + while [ $# -ne 0 ]; do + case "${1}" in + --silent) + NVM_SILENT=1 + ;; + --) + + ;; + *) + provided_version="${1-}" + ;; + esac; + shift; + done; + if [ -z "${provided_version-}" ]; then + NVM_SILENT="${NVM_SILENT:-0}" nvm_rc_version; + if [ -n "${NVM_RC_VERSION}" ]; then + provided_version="${NVM_RC_VERSION}"; + VERSION=$(nvm_version "${NVM_RC_VERSION}") || :; + fi; + unset NVM_RC_VERSION; + else + if [ "${provided_version}" != 'system' ]; then + VERSION="$(nvm_version "${provided_version}")" || :; + else + VERSION="${provided_version-}"; + fi; + fi; + if [ -z "${VERSION}" ]; then + nvm --help 1>&2; + return 127; + fi; + if [ "_${VERSION}" = '_system' ]; then + if nvm_has_system_iojs > /dev/null 2>&1 || nvm_has_system_node > /dev/null 2>&1; then + local NVM_BIN; + NVM_BIN="$(nvm use system > /dev/null 2>&1 && command which node)"; + if [ -n "${NVM_BIN}" ]; then + nvm_echo "${NVM_BIN}"; + return; + fi; + return 1; + fi; + nvm_err 'System version of node not found.'; + return 127; + else + if [ "${VERSION}" = '∞' ]; then + nvm_err "The alias \"${2}\" leads to an infinite loop. Aborting."; + return 8; + fi; + fi; + nvm_ensure_version_installed "${provided_version}"; + EXIT_CODE=$?; + if [ "${EXIT_CODE}" != "0" ]; then + return $EXIT_CODE; + fi; + local NVM_VERSION_DIR; + NVM_VERSION_DIR="$(nvm_version_path "${VERSION}")"; + nvm_echo "${NVM_VERSION_DIR}/bin/node" + ;; + "alias") + local NVM_ALIAS_DIR; + NVM_ALIAS_DIR="$(nvm_alias_path)"; + local NVM_CURRENT; + NVM_CURRENT="$(nvm_ls_current)"; + command mkdir -p "${NVM_ALIAS_DIR}/lts"; + local ALIAS; + local TARGET; + local NVM_NO_COLORS; + ALIAS='--'; + TARGET='--'; + while [ $# -gt 0 ]; do + case "${1-}" in + --) + + ;; + --no-colors) + NVM_NO_COLORS="${1}" + ;; + --*) + nvm_err "Unsupported option \"${1}\"."; + return 55 + ;; + *) + if [ "${ALIAS}" = '--' ]; then + ALIAS="${1-}"; + else + if [ "${TARGET}" = '--' ]; then + TARGET="${1-}"; + fi; + fi + ;; + esac; + shift; + done; + if [ -z "${TARGET}" ]; then + nvm unalias "${ALIAS}"; + return $?; + else + if echo "${ALIAS}" | grep -q "#"; then + nvm_err 'Aliases with a comment delimiter (#) are not supported.'; + return 1; + else + if [ "${TARGET}" != '--' ]; then + if [ "${ALIAS#*\/}" != "${ALIAS}" ]; then + nvm_err 'Aliases in subdirectories are not supported.'; + return 1; + fi; + VERSION="$(nvm_version "${TARGET}")" || :; + if [ "${VERSION}" = 'N/A' ]; then + nvm_err "! WARNING: Version '${TARGET}' does not exist."; + fi; + nvm_make_alias "${ALIAS}" "${TARGET}"; + NVM_NO_COLORS="${NVM_NO_COLORS-}" NVM_CURRENT="${NVM_CURRENT-}" DEFAULT=false nvm_print_formatted_alias "${ALIAS}" "${TARGET}" "${VERSION}"; + else + if [ "${ALIAS-}" = '--' ]; then + unset ALIAS; + fi; + nvm_list_aliases "${ALIAS-}"; + fi; + fi; + fi + ;; + "unalias") + local NVM_ALIAS_DIR; + NVM_ALIAS_DIR="$(nvm_alias_path)"; + command mkdir -p "${NVM_ALIAS_DIR}"; + if [ $# -ne 1 ]; then + nvm --help 1>&2; + return 127; + fi; + if [ "${1#*\/}" != "${1-}" ]; then + nvm_err 'Aliases in subdirectories are not supported.'; + return 1; + fi; + local NVM_IOJS_PREFIX; + local NVM_NODE_PREFIX; + NVM_IOJS_PREFIX="$(nvm_iojs_prefix)"; + NVM_NODE_PREFIX="$(nvm_node_prefix)"; + local NVM_ALIAS_EXISTS; + NVM_ALIAS_EXISTS=0; + if [ -f "${NVM_ALIAS_DIR}/${1-}" ]; then + NVM_ALIAS_EXISTS=1; + fi; + if [ $NVM_ALIAS_EXISTS -eq 0 ]; then + case "$1" in + "stable" | "unstable" | "${NVM_IOJS_PREFIX}" | "${NVM_NODE_PREFIX}" | "system") + nvm_err "${1-} is a default (built-in) alias and cannot be deleted."; + return 1 + ;; + esac; + nvm_err "Alias ${1-} doesn't exist!"; + return; + fi; + local NVM_ALIAS_ORIGINAL; + NVM_ALIAS_ORIGINAL="$(nvm_alias "${1}")"; + command rm -f "${NVM_ALIAS_DIR}/${1}"; + nvm_echo "Deleted alias ${1} - restore it with \`nvm alias \"${1}\" \"${NVM_ALIAS_ORIGINAL}\"\`" + ;; + "install-latest-npm") + if [ $# -ne 0 ]; then + nvm --help 1>&2; + return 127; + fi; + nvm_install_latest_npm + ;; + "reinstall-packages" | "copy-packages") + if [ $# -ne 1 ]; then + nvm --help 1>&2; + return 127; + fi; + local PROVIDED_VERSION; + PROVIDED_VERSION="${1-}"; + if [ "${PROVIDED_VERSION}" = "$(nvm_ls_current)" ] || [ "$(nvm_version "${PROVIDED_VERSION}" || :)" = "$(nvm_ls_current)" ]; then + nvm_err 'Can not reinstall packages from the current version of node.'; + return 2; + fi; + local VERSION; + if [ "_${PROVIDED_VERSION}" = "_system" ]; then + if ! nvm_has_system_node && ! nvm_has_system_iojs; then + nvm_err 'No system version of node or io.js detected.'; + return 3; + fi; + VERSION="system"; + else + VERSION="$(nvm_version "${PROVIDED_VERSION}")" || :; + fi; + local NPMLIST; + NPMLIST="$(nvm_npm_global_modules "${VERSION}")"; + local INSTALLS; + local LINKS; + INSTALLS="${NPMLIST%% //// *}"; + LINKS="${NPMLIST##* //// }"; + nvm_echo "Reinstalling global packages from ${VERSION}..."; + if [ -n "${INSTALLS}" ]; then + nvm_echo "${INSTALLS}" | command xargs npm install -g --quiet; + else + nvm_echo "No installed global packages found..."; + fi; + nvm_echo "Linking global packages from ${VERSION}..."; + if [ -n "${LINKS}" ]; then + ( set -f; + IFS=' +'; + for LINK in ${LINKS}; + do + set +f; + unset IFS; + if [ -n "${LINK}" ]; then + case "${LINK}" in + '/'*) + ( nvm_cd "${LINK}" && npm link ) + ;; + *) + ( nvm_cd "$(npm root -g)/../${LINK}" && npm link ) + ;; + esac; + fi; + done ); + else + nvm_echo "No linked global packages found..."; + fi + ;; + "clear-cache") + command rm -f "${NVM_DIR}/v*" "$(nvm_version_dir)" 2> /dev/null; + nvm_echo 'nvm cache cleared.' + ;; + "version") + nvm_version "${1}" + ;; + "version-remote") + local NVM_LTS; + local PATTERN; + while [ $# -gt 0 ]; do + case "${1-}" in + --) + + ;; + --lts) + NVM_LTS='*' + ;; + --lts=*) + NVM_LTS="${1##--lts=}" + ;; + --*) + nvm_err "Unsupported option \"${1}\"."; + return 55 + ;; + *) + PATTERN="${PATTERN:-${1}}" + ;; + esac; + shift; + done; + case "${PATTERN-}" in + 'lts/*') + NVM_LTS='*'; + unset PATTERN + ;; + lts/*) + NVM_LTS="${PATTERN##lts/}"; + unset PATTERN + ;; + esac; + NVM_VERSION_ONLY=true NVM_LTS="${NVM_LTS-}" nvm_remote_version "${PATTERN:-node}" + ;; + "--version" | "-v") + nvm_echo '0.40.3' + ;; + "unload") + nvm deactivate > /dev/null 2>&1; + unset -f nvm nvm_iojs_prefix nvm_node_prefix nvm_add_iojs_prefix nvm_strip_iojs_prefix nvm_is_iojs_version nvm_is_alias nvm_has_non_aliased nvm_ls_remote nvm_ls_remote_iojs nvm_ls_remote_index_tab nvm_ls nvm_remote_version nvm_remote_versions nvm_install_binary nvm_install_source nvm_clang_version nvm_get_mirror nvm_get_download_slug nvm_download_artifact nvm_install_npm_if_needed nvm_use_if_needed nvm_check_file_permissions nvm_print_versions nvm_compute_checksum nvm_get_checksum_binary nvm_get_checksum_alg nvm_get_checksum nvm_compare_checksum nvm_version nvm_rc_version nvm_match_version nvm_ensure_default_set nvm_get_arch nvm_get_os nvm_print_implicit_alias nvm_validate_implicit_alias nvm_resolve_alias nvm_ls_current nvm_alias nvm_binary_available nvm_change_path nvm_strip_path nvm_num_version_groups nvm_format_version nvm_ensure_version_prefix nvm_normalize_version nvm_is_valid_version nvm_normalize_lts nvm_ensure_version_installed nvm_cache_dir nvm_version_path nvm_alias_path nvm_version_dir nvm_find_nvmrc nvm_find_up nvm_find_project_dir nvm_tree_contains_path nvm_version_greater nvm_version_greater_than_or_equal_to nvm_print_npm_version nvm_install_latest_npm nvm_npm_global_modules nvm_has_system_node nvm_has_system_iojs nvm_download nvm_get_latest nvm_has nvm_install_default_packages nvm_get_default_packages nvm_curl_use_compression nvm_curl_version nvm_auto nvm_supports_xz nvm_echo nvm_err nvm_grep nvm_cd nvm_die_on_prefix nvm_get_make_jobs nvm_get_minor_version nvm_has_solaris_binary nvm_is_merged_node_version nvm_is_natural_num nvm_is_version_installed nvm_list_aliases nvm_make_alias nvm_print_alias_path nvm_print_default_alias nvm_print_formatted_alias nvm_resolve_local_alias nvm_sanitize_path nvm_has_colors nvm_process_parameters nvm_node_version_has_solaris_binary nvm_iojs_version_has_solaris_binary nvm_curl_libz_support nvm_command_info nvm_is_zsh nvm_stdout_is_terminal nvm_npmrc_bad_news_bears nvm_sanitize_auth_header nvm_get_colors nvm_set_colors nvm_print_color_code nvm_wrap_with_color_code nvm_format_help_message_colors nvm_echo_with_colors nvm_err_with_colors nvm_get_artifact_compression nvm_install_binary_extract nvm_extract_tarball nvm_process_nvmrc nvm_nvmrc_invalid_msg nvm_write_nvmrc > /dev/null 2>&1; + unset NVM_RC_VERSION NVM_NODEJS_ORG_MIRROR NVM_IOJS_ORG_MIRROR NVM_DIR NVM_CD_FLAGS NVM_BIN NVM_INC NVM_MAKE_JOBS NVM_COLORS INSTALLED_COLOR SYSTEM_COLOR CURRENT_COLOR NOT_INSTALLED_COLOR DEFAULT_COLOR LTS_COLOR > /dev/null 2>&1 + ;; + "set-colors") + local EXIT_CODE; + nvm_set_colors "${1-}"; + EXIT_CODE=$?; + if [ "$EXIT_CODE" -eq 17 ]; then + nvm --help 1>&2; + nvm_echo; + nvm_err_with_colors "\033[1;37mPlease pass in five \033[1;31mvalid color codes\033[1;37m. Choose from: rRgGbBcCyYmMkKeW\033[0m"; + fi + ;; + *) + nvm --help 1>&2; + return 127 + ;; + esac +} +nvm_add_iojs_prefix () +{ + nvm_echo "$(nvm_iojs_prefix)-$(nvm_ensure_version_prefix "$(nvm_strip_iojs_prefix "${1-}")")" +} +nvm_alias () +{ + local ALIAS; + ALIAS="${1-}"; + if [ -z "${ALIAS}" ]; then + nvm_err 'An alias is required.'; + return 1; + fi; + if ! ALIAS="$(nvm_normalize_lts "${ALIAS}")"; then + return $?; + fi; + if [ -z "${ALIAS}" ]; then + return 2; + fi; + local NVM_ALIAS_PATH; + NVM_ALIAS_PATH="$(nvm_alias_path)/${ALIAS}"; + if [ ! -f "${NVM_ALIAS_PATH}" ]; then + nvm_err 'Alias does not exist.'; + return 2; + fi; + command awk 'NF' "${NVM_ALIAS_PATH}" +} +nvm_alias_path () +{ + nvm_echo "$(nvm_version_dir old)/alias" +} +nvm_auto () +{ + local NVM_MODE; + NVM_MODE="${1-}"; + case "${NVM_MODE}" in + none) + return 0 + ;; + use) + local VERSION; + local NVM_CURRENT; + NVM_CURRENT="$(nvm_ls_current)"; + if [ "_${NVM_CURRENT}" = '_none' ] || [ "_${NVM_CURRENT}" = '_system' ]; then + VERSION="$(nvm_resolve_local_alias default 2> /dev/null || nvm_echo)"; + if [ -n "${VERSION}" ]; then + if [ "_${VERSION}" != '_N/A' ] && nvm_is_valid_version "${VERSION}"; then + nvm use --silent "${VERSION}" > /dev/null; + else + return 0; + fi; + else + if nvm_rc_version > /dev/null 2>&1; then + nvm use --silent > /dev/null; + fi; + fi; + else + nvm use --silent "${NVM_CURRENT}" > /dev/null; + fi + ;; + install) + local VERSION; + VERSION="$(nvm_alias default 2> /dev/null || nvm_echo)"; + if [ -n "${VERSION}" ] && [ "_${VERSION}" != '_N/A' ] && nvm_is_valid_version "${VERSION}"; then + nvm install "${VERSION}" > /dev/null; + else + if nvm_rc_version > /dev/null 2>&1; then + nvm install > /dev/null; + else + return 0; + fi; + fi + ;; + *) + nvm_err 'Invalid auto mode supplied.'; + return 1 + ;; + esac +} +nvm_binary_available () +{ + nvm_version_greater_than_or_equal_to "$(nvm_strip_iojs_prefix "${1-}")" v0.8.6 +} +nvm_cache_dir () +{ + nvm_echo "${NVM_DIR}/.cache" +} +nvm_cd () +{ + \cd "$@" +} +nvm_change_path () +{ + if [ -z "${1-}" ]; then + nvm_echo "${3-}${2-}"; + else + if ! nvm_echo "${1-}" | nvm_grep -q "${NVM_DIR}/[^/]*${2-}" && ! nvm_echo "${1-}" | nvm_grep -q "${NVM_DIR}/versions/[^/]*/[^/]*${2-}"; then + nvm_echo "${3-}${2-}:${1-}"; + else + if nvm_echo "${1-}" | nvm_grep -Eq "(^|:)(/usr(/local)?)?${2-}:.*${NVM_DIR}/[^/]*${2-}" || nvm_echo "${1-}" | nvm_grep -Eq "(^|:)(/usr(/local)?)?${2-}:.*${NVM_DIR}/versions/[^/]*/[^/]*${2-}"; then + nvm_echo "${3-}${2-}:${1-}"; + else + nvm_echo "${1-}" | command sed -e "s#${NVM_DIR}/[^/]*${2-}[^:]*#${3-}${2-}#" -e "s#${NVM_DIR}/versions/[^/]*/[^/]*${2-}[^:]*#${3-}${2-}#"; + fi; + fi; + fi +} +nvm_check_file_permissions () +{ + nvm_is_zsh && setopt local_options nonomatch; + for FILE in "$1"/* "$1"/.[!.]* "$1"/..?*; + do + if [ -d "$FILE" ]; then + if [ -n "${NVM_DEBUG-}" ]; then + nvm_err "${FILE}"; + fi; + if [ ! -L "${FILE}" ] && ! nvm_check_file_permissions "${FILE}"; then + return 2; + fi; + else + if [ -e "$FILE" ] && [ ! -w "$FILE" ] && [ ! -O "$FILE" ]; then + nvm_err "file is not writable or self-owned: $(nvm_sanitize_path "$FILE")"; + return 1; + fi; + fi; + done; + return 0 +} +nvm_clang_version () +{ + clang --version | command awk '{ if ($2 == "version") print $3; else if ($3 == "version") print $4 }' | command sed 's/-.*$//g' +} +nvm_command_info () +{ + local COMMAND; + local INFO; + COMMAND="${1}"; + if type "${COMMAND}" | nvm_grep -q hashed; then + INFO="$(type "${COMMAND}" | command sed -E 's/\(|\)//g' | command awk '{print $4}')"; + else + if type "${COMMAND}" | nvm_grep -q aliased; then + INFO="$(which "${COMMAND}") ($(type "${COMMAND}" | command awk '{ $1=$2=$3=$4="" ;print }' | command sed -e 's/^\ *//g' -Ee "s/\`|'//g"))"; + else + if type "${COMMAND}" | nvm_grep -q "^${COMMAND} is an alias for"; then + INFO="$(which "${COMMAND}") ($(type "${COMMAND}" | command awk '{ $1=$2=$3=$4=$5="" ;print }' | command sed 's/^\ *//g'))"; + else + if type "${COMMAND}" | nvm_grep -q "^${COMMAND} is /"; then + INFO="$(type "${COMMAND}" | command awk '{print $3}')"; + else + INFO="$(type "${COMMAND}")"; + fi; + fi; + fi; + fi; + nvm_echo "${INFO}" +} +nvm_compare_checksum () +{ + local FILE; + FILE="${1-}"; + if [ -z "${FILE}" ]; then + nvm_err 'Provided file to checksum is empty.'; + return 4; + else + if ! [ -f "${FILE}" ]; then + nvm_err 'Provided file to checksum does not exist.'; + return 3; + fi; + fi; + local COMPUTED_SUM; + COMPUTED_SUM="$(nvm_compute_checksum "${FILE}")"; + local CHECKSUM; + CHECKSUM="${2-}"; + if [ -z "${CHECKSUM}" ]; then + nvm_err 'Provided checksum to compare to is empty.'; + return 2; + fi; + if [ -z "${COMPUTED_SUM}" ]; then + nvm_err "Computed checksum of '${FILE}' is empty."; + nvm_err 'WARNING: Continuing *without checksum verification*'; + return; + else + if [ "${COMPUTED_SUM}" != "${CHECKSUM}" ] && [ "${COMPUTED_SUM}" != "\\${CHECKSUM}" ]; then + nvm_err "Checksums do not match: '${COMPUTED_SUM}' found, '${CHECKSUM}' expected."; + return 1; + fi; + fi; + nvm_err 'Checksums matched!' +} +nvm_compute_checksum () +{ + local FILE; + FILE="${1-}"; + if [ -z "${FILE}" ]; then + nvm_err 'Provided file to checksum is empty.'; + return 2; + else + if ! [ -f "${FILE}" ]; then + nvm_err 'Provided file to checksum does not exist.'; + return 1; + fi; + fi; + if nvm_has_non_aliased "sha256sum"; then + nvm_err 'Computing checksum with sha256sum'; + command sha256sum "${FILE}" | command awk '{print $1}'; + else + if nvm_has_non_aliased "shasum"; then + nvm_err 'Computing checksum with shasum -a 256'; + command shasum -a 256 "${FILE}" | command awk '{print $1}'; + else + if nvm_has_non_aliased "sha256"; then + nvm_err 'Computing checksum with sha256 -q'; + command sha256 -q "${FILE}" | command awk '{print $1}'; + else + if nvm_has_non_aliased "gsha256sum"; then + nvm_err 'Computing checksum with gsha256sum'; + command gsha256sum "${FILE}" | command awk '{print $1}'; + else + if nvm_has_non_aliased "openssl"; then + nvm_err 'Computing checksum with openssl dgst -sha256'; + command openssl dgst -sha256 "${FILE}" | command awk '{print $NF}'; + else + if nvm_has_non_aliased "bssl"; then + nvm_err 'Computing checksum with bssl sha256sum'; + command bssl sha256sum "${FILE}" | command awk '{print $1}'; + else + if nvm_has_non_aliased "sha1sum"; then + nvm_err 'Computing checksum with sha1sum'; + command sha1sum "${FILE}" | command awk '{print $1}'; + else + if nvm_has_non_aliased "sha1"; then + nvm_err 'Computing checksum with sha1 -q'; + command sha1 -q "${FILE}"; + fi; + fi; + fi; + fi; + fi; + fi; + fi; + fi +} +nvm_curl_libz_support () +{ + curl -V 2> /dev/null | nvm_grep "^Features:" | nvm_grep -q "libz" +} +nvm_curl_use_compression () +{ + nvm_curl_libz_support && nvm_version_greater_than_or_equal_to "$(nvm_curl_version)" 7.21.0 +} +nvm_curl_version () +{ + curl -V | command awk '{ if ($1 == "curl") print $2 }' | command sed 's/-.*$//g' +} +nvm_die_on_prefix () +{ + local NVM_DELETE_PREFIX; + NVM_DELETE_PREFIX="${1-}"; + case "${NVM_DELETE_PREFIX}" in + 0 | 1) + + ;; + *) + nvm_err 'First argument "delete the prefix" must be zero or one'; + return 1 + ;; + esac; + local NVM_COMMAND; + NVM_COMMAND="${2-}"; + local NVM_VERSION_DIR; + NVM_VERSION_DIR="${3-}"; + if [ -z "${NVM_COMMAND}" ] || [ -z "${NVM_VERSION_DIR}" ]; then + nvm_err 'Second argument "nvm command", and third argument "nvm version dir", must both be nonempty'; + return 2; + fi; + if [ -n "${PREFIX-}" ] && [ "$(nvm_version_path "$(node -v)")" != "${PREFIX}" ]; then + nvm deactivate > /dev/null 2>&1; + nvm_err "nvm is not compatible with the \"PREFIX\" environment variable: currently set to \"${PREFIX}\""; + nvm_err 'Run `unset PREFIX` to unset it.'; + return 3; + fi; + local NVM_OS; + NVM_OS="$(nvm_get_os)"; + local NVM_NPM_CONFIG_x_PREFIX_ENV; + NVM_NPM_CONFIG_x_PREFIX_ENV="$(command awk 'BEGIN { for (name in ENVIRON) if (toupper(name) == "NPM_CONFIG_PREFIX") { print name; break } }')"; + if [ -n "${NVM_NPM_CONFIG_x_PREFIX_ENV-}" ]; then + local NVM_CONFIG_VALUE; + eval "NVM_CONFIG_VALUE=\"\$${NVM_NPM_CONFIG_x_PREFIX_ENV}\""; + if [ -n "${NVM_CONFIG_VALUE-}" ] && [ "_${NVM_OS}" = "_win" ]; then + NVM_CONFIG_VALUE="$(cd "$NVM_CONFIG_VALUE" 2> /dev/null && pwd)"; + fi; + if [ -n "${NVM_CONFIG_VALUE-}" ] && ! nvm_tree_contains_path "${NVM_DIR}" "${NVM_CONFIG_VALUE}"; then + nvm deactivate > /dev/null 2>&1; + nvm_err "nvm is not compatible with the \"${NVM_NPM_CONFIG_x_PREFIX_ENV}\" environment variable: currently set to \"${NVM_CONFIG_VALUE}\""; + nvm_err "Run \`unset ${NVM_NPM_CONFIG_x_PREFIX_ENV}\` to unset it."; + return 4; + fi; + fi; + local NVM_NPM_BUILTIN_NPMRC; + NVM_NPM_BUILTIN_NPMRC="${NVM_VERSION_DIR}/lib/node_modules/npm/npmrc"; + if nvm_npmrc_bad_news_bears "${NVM_NPM_BUILTIN_NPMRC}"; then + if [ "_${NVM_DELETE_PREFIX}" = "_1" ]; then + npm config --loglevel=warn delete prefix --userconfig="${NVM_NPM_BUILTIN_NPMRC}"; + npm config --loglevel=warn delete globalconfig --userconfig="${NVM_NPM_BUILTIN_NPMRC}"; + else + nvm_err "Your builtin npmrc file ($(nvm_sanitize_path "${NVM_NPM_BUILTIN_NPMRC}"))"; + nvm_err 'has a `globalconfig` and/or a `prefix` setting, which are incompatible with nvm.'; + nvm_err "Run \`${NVM_COMMAND}\` to unset it."; + return 10; + fi; + fi; + local NVM_NPM_GLOBAL_NPMRC; + NVM_NPM_GLOBAL_NPMRC="${NVM_VERSION_DIR}/etc/npmrc"; + if nvm_npmrc_bad_news_bears "${NVM_NPM_GLOBAL_NPMRC}"; then + if [ "_${NVM_DELETE_PREFIX}" = "_1" ]; then + npm config --global --loglevel=warn delete prefix; + npm config --global --loglevel=warn delete globalconfig; + else + nvm_err "Your global npmrc file ($(nvm_sanitize_path "${NVM_NPM_GLOBAL_NPMRC}"))"; + nvm_err 'has a `globalconfig` and/or a `prefix` setting, which are incompatible with nvm.'; + nvm_err "Run \`${NVM_COMMAND}\` to unset it."; + return 10; + fi; + fi; + local NVM_NPM_USER_NPMRC; + NVM_NPM_USER_NPMRC="${HOME}/.npmrc"; + if nvm_npmrc_bad_news_bears "${NVM_NPM_USER_NPMRC}"; then + if [ "_${NVM_DELETE_PREFIX}" = "_1" ]; then + npm config --loglevel=warn delete prefix --userconfig="${NVM_NPM_USER_NPMRC}"; + npm config --loglevel=warn delete globalconfig --userconfig="${NVM_NPM_USER_NPMRC}"; + else + nvm_err "Your user’s .npmrc file ($(nvm_sanitize_path "${NVM_NPM_USER_NPMRC}"))"; + nvm_err 'has a `globalconfig` and/or a `prefix` setting, which are incompatible with nvm.'; + nvm_err "Run \`${NVM_COMMAND}\` to unset it."; + return 10; + fi; + fi; + local NVM_NPM_PROJECT_NPMRC; + NVM_NPM_PROJECT_NPMRC="$(nvm_find_project_dir)/.npmrc"; + if nvm_npmrc_bad_news_bears "${NVM_NPM_PROJECT_NPMRC}"; then + if [ "_${NVM_DELETE_PREFIX}" = "_1" ]; then + npm config --loglevel=warn delete prefix; + npm config --loglevel=warn delete globalconfig; + else + nvm_err "Your project npmrc file ($(nvm_sanitize_path "${NVM_NPM_PROJECT_NPMRC}"))"; + nvm_err 'has a `globalconfig` and/or a `prefix` setting, which are incompatible with nvm.'; + nvm_err "Run \`${NVM_COMMAND}\` to unset it."; + return 10; + fi; + fi +} +nvm_download () +{ + if nvm_has "curl"; then + local CURL_COMPRESSED_FLAG=""; + local CURL_HEADER_FLAG=""; + if [ -n "${NVM_AUTH_HEADER:-}" ]; then + sanitized_header=$(nvm_sanitize_auth_header "${NVM_AUTH_HEADER}"); + CURL_HEADER_FLAG="--header \"Authorization: ${sanitized_header}\""; + fi; + if nvm_curl_use_compression; then + CURL_COMPRESSED_FLAG="--compressed"; + fi; + local NVM_DOWNLOAD_ARGS; + NVM_DOWNLOAD_ARGS=''; + for arg in "$@"; + do + NVM_DOWNLOAD_ARGS="${NVM_DOWNLOAD_ARGS} \"$arg\""; + done; + eval "curl -q --fail ${CURL_COMPRESSED_FLAG:-} ${CURL_HEADER_FLAG:-} ${NVM_DOWNLOAD_ARGS}"; + else + if nvm_has "wget"; then + ARGS=$(nvm_echo "$@" | command sed " + s/--progress-bar /--progress=bar / + s/--compressed // + s/--fail // + s/-L // + s/-I /--server-response / + s/-s /-q / + s/-sS /-nv / + s/-o /-O / + s/-C - /-c / + "); + if [ -n "${NVM_AUTH_HEADER:-}" ]; then + ARGS="${ARGS} --header \"${NVM_AUTH_HEADER}\""; + fi; + eval wget $ARGS; + fi; + fi +} +nvm_download_artifact () +{ + local FLAVOR; + case "${1-}" in + node | iojs) + FLAVOR="${1}" + ;; + *) + nvm_err 'supported flavors: node, iojs'; + return 1 + ;; + esac; + local KIND; + case "${2-}" in + binary | source) + KIND="${2}" + ;; + *) + nvm_err 'supported kinds: binary, source'; + return 1 + ;; + esac; + local TYPE; + TYPE="${3-}"; + local MIRROR; + MIRROR="$(nvm_get_mirror "${FLAVOR}" "${TYPE}")"; + if [ -z "${MIRROR}" ]; then + return 2; + fi; + local VERSION; + VERSION="${4}"; + if [ -z "${VERSION}" ]; then + nvm_err 'A version number is required.'; + return 3; + fi; + if [ "${KIND}" = 'binary' ] && ! nvm_binary_available "${VERSION}"; then + nvm_err "No precompiled binary available for ${VERSION}."; + return; + fi; + local SLUG; + SLUG="$(nvm_get_download_slug "${FLAVOR}" "${KIND}" "${VERSION}")"; + local COMPRESSION; + COMPRESSION="$(nvm_get_artifact_compression "${VERSION}")"; + local CHECKSUM; + CHECKSUM="$(nvm_get_checksum "${FLAVOR}" "${TYPE}" "${VERSION}" "${SLUG}" "${COMPRESSION}")"; + local tmpdir; + if [ "${KIND}" = 'binary' ]; then + tmpdir="$(nvm_cache_dir)/bin/${SLUG}"; + else + tmpdir="$(nvm_cache_dir)/src/${SLUG}"; + fi; + command mkdir -p "${tmpdir}/files" || ( nvm_err "creating directory ${tmpdir}/files failed"; + return 3 ); + local TARBALL; + TARBALL="${tmpdir}/${SLUG}.${COMPRESSION}"; + local TARBALL_URL; + if nvm_version_greater_than_or_equal_to "${VERSION}" 0.1.14; then + TARBALL_URL="${MIRROR}/${VERSION}/${SLUG}.${COMPRESSION}"; + else + TARBALL_URL="${MIRROR}/${SLUG}.${COMPRESSION}"; + fi; + if [ -r "${TARBALL}" ]; then + nvm_err "Local cache found: $(nvm_sanitize_path "${TARBALL}")"; + if nvm_compare_checksum "${TARBALL}" "${CHECKSUM}" > /dev/null 2>&1; then + nvm_err "Checksums match! Using existing downloaded archive $(nvm_sanitize_path "${TARBALL}")"; + nvm_echo "${TARBALL}"; + return 0; + fi; + nvm_compare_checksum "${TARBALL}" "${CHECKSUM}"; + nvm_err "Checksum check failed!"; + nvm_err "Removing the broken local cache..."; + command rm -rf "${TARBALL}"; + fi; + nvm_err "Downloading ${TARBALL_URL}..."; + nvm_download -L -C - "${PROGRESS_BAR}" "${TARBALL_URL}" -o "${TARBALL}" || ( command rm -rf "${TARBALL}" "${tmpdir}"; + nvm_err "download from ${TARBALL_URL} failed"; + return 4 ); + if nvm_grep '404 Not Found' "${TARBALL}" > /dev/null; then + command rm -rf "${TARBALL}" "${tmpdir}"; + nvm_err "HTTP 404 at URL ${TARBALL_URL}"; + return 5; + fi; + nvm_compare_checksum "${TARBALL}" "${CHECKSUM}" || ( command rm -rf "${tmpdir}/files"; + return 6 ); + nvm_echo "${TARBALL}" +} +nvm_echo () +{ + command printf %s\\n "$*" 2> /dev/null +} +nvm_echo_with_colors () +{ + command printf %b\\n "$*" 2> /dev/null +} +nvm_ensure_default_set () +{ + local VERSION; + VERSION="$1"; + if [ -z "${VERSION}" ]; then + nvm_err 'nvm_ensure_default_set: a version is required'; + return 1; + else + if nvm_alias default > /dev/null 2>&1; then + return 0; + fi; + fi; + local OUTPUT; + OUTPUT="$(nvm alias default "${VERSION}")"; + local EXIT_CODE; + EXIT_CODE="$?"; + nvm_echo "Creating default alias: ${OUTPUT}"; + return $EXIT_CODE +} +nvm_ensure_version_installed () +{ + local PROVIDED_VERSION; + PROVIDED_VERSION="${1-}"; + local IS_VERSION_FROM_NVMRC; + IS_VERSION_FROM_NVMRC="${2-}"; + if [ "${PROVIDED_VERSION}" = 'system' ]; then + if nvm_has_system_iojs || nvm_has_system_node; then + return 0; + fi; + nvm_err "N/A: no system version of node/io.js is installed."; + return 1; + fi; + local LOCAL_VERSION; + local EXIT_CODE; + LOCAL_VERSION="$(nvm_version "${PROVIDED_VERSION}")"; + EXIT_CODE="$?"; + local NVM_VERSION_DIR; + if [ "${EXIT_CODE}" != "0" ] || ! nvm_is_version_installed "${LOCAL_VERSION}"; then + if VERSION="$(nvm_resolve_alias "${PROVIDED_VERSION}")"; then + nvm_err "N/A: version \"${PROVIDED_VERSION} -> ${VERSION}\" is not yet installed."; + else + local PREFIXED_VERSION; + PREFIXED_VERSION="$(nvm_ensure_version_prefix "${PROVIDED_VERSION}")"; + nvm_err "N/A: version \"${PREFIXED_VERSION:-$PROVIDED_VERSION}\" is not yet installed."; + fi; + nvm_err ""; + if [ "${PROVIDED_VERSION}" = 'lts' ]; then + nvm_err '`lts` is not an alias - you may need to run `nvm install --lts` to install and `nvm use --lts` to use it.'; + else + if [ "${IS_VERSION_FROM_NVMRC}" != '1' ]; then + nvm_err "You need to run \`nvm install ${PROVIDED_VERSION}\` to install and use it."; + else + nvm_err 'You need to run `nvm install` to install and use the node version specified in `.nvmrc`.'; + fi; + fi; + return 1; + fi +} +nvm_ensure_version_prefix () +{ + local NVM_VERSION; + NVM_VERSION="$(nvm_strip_iojs_prefix "${1-}" | command sed -e 's/^\([0-9]\)/v\1/g')"; + if nvm_is_iojs_version "${1-}"; then + nvm_add_iojs_prefix "${NVM_VERSION}"; + else + nvm_echo "${NVM_VERSION}"; + fi +} +nvm_err () +{ + nvm_echo "$@" 1>&2 +} +nvm_err_with_colors () +{ + nvm_echo_with_colors "$@" 1>&2 +} +nvm_extract_tarball () +{ + if [ "$#" -ne 4 ]; then + nvm_err 'nvm_extract_tarball requires exactly 4 arguments'; + return 5; + fi; + local NVM_OS; + NVM_OS="${1-}"; + local VERSION; + VERSION="${2-}"; + local TARBALL; + TARBALL="${3-}"; + local TMPDIR; + TMPDIR="${4-}"; + local tar_compression_flag; + tar_compression_flag='z'; + if nvm_supports_xz "${VERSION}"; then + tar_compression_flag='J'; + fi; + local tar; + tar='tar'; + if [ "${NVM_OS}" = 'aix' ]; then + tar='gtar'; + fi; + if [ "${NVM_OS}" = 'openbsd' ]; then + if [ "${tar_compression_flag}" = 'J' ]; then + command xzcat "${TARBALL}" | "${tar}" -xf - -C "${TMPDIR}" -s '/[^\/]*\///' || return 1; + else + command "${tar}" -x${tar_compression_flag}f "${TARBALL}" -C "${TMPDIR}" -s '/[^\/]*\///' || return 1; + fi; + else + command "${tar}" -x${tar_compression_flag}f "${TARBALL}" -C "${TMPDIR}" --strip-components 1 || return 1; + fi +} +nvm_find_nvmrc () +{ + local dir; + dir="$(nvm_find_up '.nvmrc')"; + if [ -e "${dir}/.nvmrc" ]; then + nvm_echo "${dir}/.nvmrc"; + fi +} +nvm_find_project_dir () +{ + local path_; + path_="${PWD}"; + while [ "${path_}" != "" ] && [ "${path_}" != '.' ] && [ ! -f "${path_}/package.json" ] && [ ! -d "${path_}/node_modules" ]; do + path_=${path_%/*}; + done; + nvm_echo "${path_}" +} +nvm_find_up () +{ + local path_; + path_="${PWD}"; + while [ "${path_}" != "" ] && [ "${path_}" != '.' ] && [ ! -f "${path_}/${1-}" ]; do + path_=${path_%/*}; + done; + nvm_echo "${path_}" +} +nvm_format_version () +{ + local VERSION; + VERSION="$(nvm_ensure_version_prefix "${1-}")"; + local NUM_GROUPS; + NUM_GROUPS="$(nvm_num_version_groups "${VERSION}")"; + if [ "${NUM_GROUPS}" -lt 3 ]; then + nvm_format_version "${VERSION%.}.0"; + else + nvm_echo "${VERSION}" | command cut -f1-3 -d.; + fi +} +nvm_get_arch () +{ + local HOST_ARCH; + local NVM_OS; + local EXIT_CODE; + local LONG_BIT; + NVM_OS="$(nvm_get_os)"; + if [ "_${NVM_OS}" = "_sunos" ]; then + if HOST_ARCH=$(pkg_info -Q MACHINE_ARCH pkg_install); then + HOST_ARCH=$(nvm_echo "${HOST_ARCH}" | command tail -1); + else + HOST_ARCH=$(isainfo -n); + fi; + else + if [ "_${NVM_OS}" = "_aix" ]; then + HOST_ARCH=ppc64; + else + HOST_ARCH="$(command uname -m)"; + LONG_BIT="$(getconf LONG_BIT 2> /dev/null)"; + fi; + fi; + local NVM_ARCH; + case "${HOST_ARCH}" in + x86_64 | amd64) + NVM_ARCH="x64" + ;; + i*86) + NVM_ARCH="x86" + ;; + aarch64 | armv8l) + NVM_ARCH="arm64" + ;; + *) + NVM_ARCH="${HOST_ARCH}" + ;; + esac; + if [ "_${LONG_BIT}" = "_32" ] && [ "${NVM_ARCH}" = "x64" ]; then + NVM_ARCH="x86"; + fi; + if [ "$(uname)" = "Linux" ] && [ "${NVM_ARCH}" = arm64 ] && [ "$(command od -An -t x1 -j 4 -N 1 "/sbin/init" 2> /dev/null)" = ' 01' ]; then + NVM_ARCH=armv7l; + HOST_ARCH=armv7l; + fi; + if [ -f "/etc/alpine-release" ]; then + NVM_ARCH=x64-musl; + fi; + nvm_echo "${NVM_ARCH}" +} +nvm_get_artifact_compression () +{ + local VERSION; + VERSION="${1-}"; + local NVM_OS; + NVM_OS="$(nvm_get_os)"; + local COMPRESSION; + COMPRESSION='tar.gz'; + if [ "_${NVM_OS}" = '_win' ]; then + COMPRESSION='zip'; + else + if nvm_supports_xz "${VERSION}"; then + COMPRESSION='tar.xz'; + fi; + fi; + nvm_echo "${COMPRESSION}" +} +nvm_get_checksum () +{ + local FLAVOR; + case "${1-}" in + node | iojs) + FLAVOR="${1}" + ;; + *) + nvm_err 'supported flavors: node, iojs'; + return 2 + ;; + esac; + local MIRROR; + MIRROR="$(nvm_get_mirror "${FLAVOR}" "${2-}")"; + if [ -z "${MIRROR}" ]; then + return 1; + fi; + local SHASUMS_URL; + if [ "$(nvm_get_checksum_alg)" = 'sha-256' ]; then + SHASUMS_URL="${MIRROR}/${3}/SHASUMS256.txt"; + else + SHASUMS_URL="${MIRROR}/${3}/SHASUMS.txt"; + fi; + nvm_download -L -s "${SHASUMS_URL}" -o - | command awk "{ if (\"${4}.${5}\" == \$2) print \$1}" +} +nvm_get_checksum_alg () +{ + local NVM_CHECKSUM_BIN; + NVM_CHECKSUM_BIN="$(nvm_get_checksum_binary 2> /dev/null)"; + case "${NVM_CHECKSUM_BIN-}" in + sha256sum | shasum | sha256 | gsha256sum | openssl | bssl) + nvm_echo 'sha-256' + ;; + sha1sum | sha1) + nvm_echo 'sha-1' + ;; + *) + nvm_get_checksum_binary; + return $? + ;; + esac +} +nvm_get_checksum_binary () +{ + if nvm_has_non_aliased 'sha256sum'; then + nvm_echo 'sha256sum'; + else + if nvm_has_non_aliased 'shasum'; then + nvm_echo 'shasum'; + else + if nvm_has_non_aliased 'sha256'; then + nvm_echo 'sha256'; + else + if nvm_has_non_aliased 'gsha256sum'; then + nvm_echo 'gsha256sum'; + else + if nvm_has_non_aliased 'openssl'; then + nvm_echo 'openssl'; + else + if nvm_has_non_aliased 'bssl'; then + nvm_echo 'bssl'; + else + if nvm_has_non_aliased 'sha1sum'; then + nvm_echo 'sha1sum'; + else + if nvm_has_non_aliased 'sha1'; then + nvm_echo 'sha1'; + else + nvm_err 'Unaliased sha256sum, shasum, sha256, gsha256sum, openssl, or bssl not found.'; + nvm_err 'Unaliased sha1sum or sha1 not found.'; + return 1; + fi; + fi; + fi; + fi; + fi; + fi; + fi; + fi +} +nvm_get_colors () +{ + local COLOR; + local SYS_COLOR; + local COLORS; + COLORS="${NVM_COLORS:-bygre}"; + case $1 in + 1) + COLOR=$(nvm_print_color_code "$(echo "$COLORS" | awk '{ print substr($0, 1, 1); }')") + ;; + 2) + COLOR=$(nvm_print_color_code "$(echo "$COLORS" | awk '{ print substr($0, 2, 1); }')") + ;; + 3) + COLOR=$(nvm_print_color_code "$(echo "$COLORS" | awk '{ print substr($0, 3, 1); }')") + ;; + 4) + COLOR=$(nvm_print_color_code "$(echo "$COLORS" | awk '{ print substr($0, 4, 1); }')") + ;; + 5) + COLOR=$(nvm_print_color_code "$(echo "$COLORS" | awk '{ print substr($0, 5, 1); }')") + ;; + 6) + SYS_COLOR=$(nvm_print_color_code "$(echo "$COLORS" | awk '{ print substr($0, 2, 1); }')"); + COLOR=$(nvm_echo "$SYS_COLOR" | command tr '0;' '1;') + ;; + *) + nvm_err "Invalid color index, ${1-}"; + return 1 + ;; + esac; + nvm_echo "$COLOR" +} +nvm_get_default_packages () +{ + local NVM_DEFAULT_PACKAGE_FILE; + NVM_DEFAULT_PACKAGE_FILE="${NVM_DIR}/default-packages"; + if [ -f "${NVM_DEFAULT_PACKAGE_FILE}" ]; then + command awk -v filename="${NVM_DEFAULT_PACKAGE_FILE}" ' + /^[[:space:]]*#/ { next } # Skip lines that begin with # + /^[[:space:]]*$/ { next } # Skip empty lines + /[[:space:]]/ && !/^[[:space:]]*#/ { + print "Only one package per line is allowed in `" filename "`. Please remove any lines with multiple space-separated values." > "/dev/stderr" + err = 1 + exit 1 + } + { + if (NR > 1 && !prev_space) printf " " + printf "%s", $0 + prev_space = 0 + } + ' "${NVM_DEFAULT_PACKAGE_FILE}"; + fi +} +nvm_get_download_slug () +{ + local FLAVOR; + case "${1-}" in + node | iojs) + FLAVOR="${1}" + ;; + *) + nvm_err 'supported flavors: node, iojs'; + return 1 + ;; + esac; + local KIND; + case "${2-}" in + binary | source) + KIND="${2}" + ;; + *) + nvm_err 'supported kinds: binary, source'; + return 2 + ;; + esac; + local VERSION; + VERSION="${3-}"; + local NVM_OS; + NVM_OS="$(nvm_get_os)"; + local NVM_ARCH; + NVM_ARCH="$(nvm_get_arch)"; + if ! nvm_is_merged_node_version "${VERSION}"; then + if [ "${NVM_ARCH}" = 'armv6l' ] || [ "${NVM_ARCH}" = 'armv7l' ]; then + NVM_ARCH="arm-pi"; + fi; + fi; + if nvm_version_greater '14.17.0' "${VERSION}" || ( nvm_version_greater_than_or_equal_to "${VERSION}" '15.0.0' && nvm_version_greater '16.0.0' "${VERSION}" ); then + if [ "_${NVM_OS}" = '_darwin' ] && [ "${NVM_ARCH}" = 'arm64' ]; then + NVM_ARCH=x64; + fi; + fi; + if [ "${KIND}" = 'binary' ]; then + nvm_echo "${FLAVOR}-${VERSION}-${NVM_OS}-${NVM_ARCH}"; + else + if [ "${KIND}" = 'source' ]; then + nvm_echo "${FLAVOR}-${VERSION}"; + fi; + fi +} +nvm_get_latest () +{ + local NVM_LATEST_URL; + local CURL_COMPRESSED_FLAG; + if nvm_has "curl"; then + if nvm_curl_use_compression; then + CURL_COMPRESSED_FLAG="--compressed"; + fi; + NVM_LATEST_URL="$(curl ${CURL_COMPRESSED_FLAG:-} -q -w "%{url_effective}\\n" -L -s -S https://latest.nvm.sh -o /dev/null)"; + else + if nvm_has "wget"; then + NVM_LATEST_URL="$(wget -q https://latest.nvm.sh --server-response -O /dev/null 2>&1 | command awk '/^ Location: /{DEST=$2} END{ print DEST }')"; + else + nvm_err 'nvm needs curl or wget to proceed.'; + return 1; + fi; + fi; + if [ -z "${NVM_LATEST_URL}" ]; then + nvm_err "https://latest.nvm.sh did not redirect to the latest release on GitHub"; + return 2; + fi; + nvm_echo "${NVM_LATEST_URL##*/}" +} +nvm_get_make_jobs () +{ + if nvm_is_natural_num "${1-}"; then + NVM_MAKE_JOBS="$1"; + nvm_echo "number of \`make\` jobs: ${NVM_MAKE_JOBS}"; + return; + else + if [ -n "${1-}" ]; then + unset NVM_MAKE_JOBS; + nvm_err "$1 is invalid for number of \`make\` jobs, must be a natural number"; + fi; + fi; + local NVM_OS; + NVM_OS="$(nvm_get_os)"; + local NVM_CPU_CORES; + case "_${NVM_OS}" in + "_linux") + NVM_CPU_CORES="$(nvm_grep -c -E '^processor.+: [0-9]+' /proc/cpuinfo)" + ;; + "_freebsd" | "_darwin" | "_openbsd") + NVM_CPU_CORES="$(sysctl -n hw.ncpu)" + ;; + "_sunos") + NVM_CPU_CORES="$(psrinfo | wc -l)" + ;; + "_aix") + NVM_CPU_CORES="$(pmcycles -m | wc -l)" + ;; + esac; + if ! nvm_is_natural_num "${NVM_CPU_CORES}"; then + nvm_err 'Can not determine how many core(s) are available, running in single-threaded mode.'; + nvm_err 'Please report an issue on GitHub to help us make nvm run faster on your computer!'; + NVM_MAKE_JOBS=1; + else + nvm_echo "Detected that you have ${NVM_CPU_CORES} CPU core(s)"; + if [ "${NVM_CPU_CORES}" -gt 2 ]; then + NVM_MAKE_JOBS=$((NVM_CPU_CORES - 1)); + nvm_echo "Running with ${NVM_MAKE_JOBS} threads to speed up the build"; + else + NVM_MAKE_JOBS=1; + nvm_echo 'Number of CPU core(s) less than or equal to 2, running in single-threaded mode'; + fi; + fi +} +nvm_get_minor_version () +{ + local VERSION; + VERSION="$1"; + if [ -z "${VERSION}" ]; then + nvm_err 'a version is required'; + return 1; + fi; + case "${VERSION}" in + v | .* | *..* | v*[!.0123456789]* | [!v]*[!.0123456789]* | [!v0123456789]* | v[!0123456789]*) + nvm_err 'invalid version number'; + return 2 + ;; + esac; + local PREFIXED_VERSION; + PREFIXED_VERSION="$(nvm_format_version "${VERSION}")"; + local MINOR; + MINOR="$(nvm_echo "${PREFIXED_VERSION}" | nvm_grep -e '^v' | command cut -c2- | command cut -d . -f 1,2)"; + if [ -z "${MINOR}" ]; then + nvm_err 'invalid version number! (please report this)'; + return 3; + fi; + nvm_echo "${MINOR}" +} +nvm_get_mirror () +{ + local NVM_MIRROR; + NVM_MIRROR=''; + case "${1}-${2}" in + node-std) + NVM_MIRROR="${NVM_NODEJS_ORG_MIRROR:-https://nodejs.org/dist}" + ;; + iojs-std) + NVM_MIRROR="${NVM_IOJS_ORG_MIRROR:-https://iojs.org/dist}" + ;; + *) + nvm_err 'unknown type of node.js or io.js release'; + return 1 + ;; + esac; + case "${NVM_MIRROR}" in + *\`* | *\\* | *\'* | *\(* | *' '*) + nvm_err '$NVM_NODEJS_ORG_MIRROR and $NVM_IOJS_ORG_MIRROR may only contain a URL'; + return 2 + ;; + esac; + if ! nvm_echo "${NVM_MIRROR}" | command awk '{ $0 ~ "^https?://[a-zA-Z0-9./_-]+$" }'; then + nvm_err '$NVM_NODEJS_ORG_MIRROR and $NVM_IOJS_ORG_MIRROR may only contain a URL'; + return 2; + fi; + nvm_echo "${NVM_MIRROR}" +} +nvm_get_os () +{ + local NVM_UNAME; + NVM_UNAME="$(command uname -a)"; + local NVM_OS; + case "${NVM_UNAME}" in + Linux\ *) + NVM_OS=linux + ;; + Darwin\ *) + NVM_OS=darwin + ;; + SunOS\ *) + NVM_OS=sunos + ;; + FreeBSD\ *) + NVM_OS=freebsd + ;; + OpenBSD\ *) + NVM_OS=openbsd + ;; + AIX\ *) + NVM_OS=aix + ;; + CYGWIN* | MSYS* | MINGW*) + NVM_OS=win + ;; + esac; + nvm_echo "${NVM_OS-}" +} +nvm_grep () +{ + GREP_OPTIONS='' command grep "$@" +} +nvm_has () +{ + type "${1-}" > /dev/null 2>&1 +} +nvm_has_colors () +{ + local NVM_NUM_COLORS; + if nvm_has tput; then + NVM_NUM_COLORS="$(command tput -T "${TERM:-vt100}" colors)"; + fi; + [ "${NVM_NUM_COLORS:--1}" -ge 8 ] && [ "${NVM_NO_COLORS-}" != '--no-colors' ] +} +nvm_has_non_aliased () +{ + nvm_has "${1-}" && ! nvm_is_alias "${1-}" +} +nvm_has_solaris_binary () +{ + local VERSION="${1-}"; + if nvm_is_merged_node_version "${VERSION}"; then + return 0; + else + if nvm_is_iojs_version "${VERSION}"; then + nvm_iojs_version_has_solaris_binary "${VERSION}"; + else + nvm_node_version_has_solaris_binary "${VERSION}"; + fi; + fi +} +nvm_has_system_iojs () +{ + [ "$(nvm deactivate > /dev/null 2>&1 && command -v iojs)" != '' ] +} +nvm_has_system_node () +{ + [ "$(nvm deactivate > /dev/null 2>&1 && command -v node)" != '' ] +} +nvm_install_binary () +{ + local FLAVOR; + case "${1-}" in + node | iojs) + FLAVOR="${1}" + ;; + *) + nvm_err 'supported flavors: node, iojs'; + return 4 + ;; + esac; + local TYPE; + TYPE="${2-}"; + local PREFIXED_VERSION; + PREFIXED_VERSION="${3-}"; + if [ -z "${PREFIXED_VERSION}" ]; then + nvm_err 'A version number is required.'; + return 3; + fi; + local nosource; + nosource="${4-}"; + local VERSION; + VERSION="$(nvm_strip_iojs_prefix "${PREFIXED_VERSION}")"; + local NVM_OS; + NVM_OS="$(nvm_get_os)"; + if [ -z "${NVM_OS}" ]; then + return 2; + fi; + local TARBALL; + local TMPDIR; + local PROGRESS_BAR; + local NODE_OR_IOJS; + if [ "${FLAVOR}" = 'node' ]; then + NODE_OR_IOJS="${FLAVOR}"; + else + if [ "${FLAVOR}" = 'iojs' ]; then + NODE_OR_IOJS="io.js"; + fi; + fi; + if [ "${NVM_NO_PROGRESS-}" = "1" ]; then + PROGRESS_BAR="-sS"; + else + PROGRESS_BAR="--progress-bar"; + fi; + nvm_echo "Downloading and installing ${NODE_OR_IOJS-} ${VERSION}..."; + TARBALL="$(PROGRESS_BAR="${PROGRESS_BAR}" nvm_download_artifact "${FLAVOR}" binary "${TYPE-}" "${VERSION}" | command tail -1)"; + if [ -f "${TARBALL}" ]; then + TMPDIR="$(dirname "${TARBALL}")/files"; + fi; + if nvm_install_binary_extract "${NVM_OS}" "${PREFIXED_VERSION}" "${VERSION}" "${TARBALL}" "${TMPDIR}"; then + if [ -n "${ALIAS-}" ]; then + nvm alias "${ALIAS}" "${provided_version}"; + fi; + return 0; + fi; + if [ "${nosource-}" = '1' ]; then + nvm_err 'Binary download failed. Download from source aborted.'; + return 0; + fi; + nvm_err 'Binary download failed, trying source.'; + if [ -n "${TMPDIR-}" ]; then + command rm -rf "${TMPDIR}"; + fi; + return 1 +} +nvm_install_binary_extract () +{ + if [ "$#" -ne 5 ]; then + nvm_err 'nvm_install_binary_extract needs 5 parameters'; + return 1; + fi; + local NVM_OS; + local PREFIXED_VERSION; + local VERSION; + local TARBALL; + local TMPDIR; + NVM_OS="${1}"; + PREFIXED_VERSION="${2}"; + VERSION="${3}"; + TARBALL="${4}"; + TMPDIR="${5}"; + local VERSION_PATH; + [ -n "${TMPDIR-}" ] && command mkdir -p "${TMPDIR}" && VERSION_PATH="$(nvm_version_path "${PREFIXED_VERSION}")" || return 1; + if [ "${NVM_OS}" = 'win' ]; then + VERSION_PATH="${VERSION_PATH}/bin"; + command unzip -q "${TARBALL}" -d "${TMPDIR}" || return 1; + else + nvm_extract_tarball "${NVM_OS}" "${VERSION}" "${TARBALL}" "${TMPDIR}"; + fi; + command mkdir -p "${VERSION_PATH}" || return 1; + if [ "${NVM_OS}" = 'win' ]; then + command mv "${TMPDIR}/"*/* "${VERSION_PATH}/" || return 1; + command chmod +x "${VERSION_PATH}"/node.exe || return 1; + command chmod +x "${VERSION_PATH}"/npm || return 1; + command chmod +x "${VERSION_PATH}"/npx 2> /dev/null; + else + command mv "${TMPDIR}/"* "${VERSION_PATH}" || return 1; + fi; + command rm -rf "${TMPDIR}"; + return 0 +} +nvm_install_default_packages () +{ + local DEFAULT_PACKAGES; + DEFAULT_PACKAGES="$(nvm_get_default_packages)"; + EXIT_CODE=$?; + if [ $EXIT_CODE -ne 0 ] || [ -z "${DEFAULT_PACKAGES}" ]; then + return $EXIT_CODE; + fi; + nvm_echo "Installing default global packages from ${NVM_DIR}/default-packages..."; + nvm_echo "npm install -g --quiet ${DEFAULT_PACKAGES}"; + if ! nvm_echo "${DEFAULT_PACKAGES}" | command xargs npm install -g --quiet; then + nvm_err "Failed installing default packages. Please check if your default-packages file or a package in it has problems!"; + return 1; + fi +} +nvm_install_latest_npm () +{ + nvm_echo 'Attempting to upgrade to the latest working version of npm...'; + local NODE_VERSION; + NODE_VERSION="$(nvm_strip_iojs_prefix "$(nvm_ls_current)")"; + local NPM_VERSION; + NPM_VERSION="$(npm --version 2> /dev/null)"; + if [ "${NODE_VERSION}" = 'system' ]; then + NODE_VERSION="$(node --version)"; + else + if [ "${NODE_VERSION}" = 'none' ]; then + nvm_echo "Detected node version ${NODE_VERSION}, npm version v${NPM_VERSION}"; + NODE_VERSION=''; + fi; + fi; + if [ -z "${NODE_VERSION}" ]; then + nvm_err 'Unable to obtain node version.'; + return 1; + fi; + if [ -z "${NPM_VERSION}" ]; then + nvm_err 'Unable to obtain npm version.'; + return 2; + fi; + local NVM_NPM_CMD; + NVM_NPM_CMD='npm'; + if [ "${NVM_DEBUG-}" = 1 ]; then + nvm_echo "Detected node version ${NODE_VERSION}, npm version v${NPM_VERSION}"; + NVM_NPM_CMD='nvm_echo npm'; + fi; + local NVM_IS_0_6; + NVM_IS_0_6=0; + if nvm_version_greater_than_or_equal_to "${NODE_VERSION}" 0.6.0 && nvm_version_greater 0.7.0 "${NODE_VERSION}"; then + NVM_IS_0_6=1; + fi; + local NVM_IS_0_9; + NVM_IS_0_9=0; + if nvm_version_greater_than_or_equal_to "${NODE_VERSION}" 0.9.0 && nvm_version_greater 0.10.0 "${NODE_VERSION}"; then + NVM_IS_0_9=1; + fi; + if [ $NVM_IS_0_6 -eq 1 ]; then + nvm_echo '* `node` v0.6.x can only upgrade to `npm` v1.3.x'; + $NVM_NPM_CMD install -g npm@1.3; + else + if [ $NVM_IS_0_9 -eq 0 ]; then + if nvm_version_greater_than_or_equal_to "${NPM_VERSION}" 1.0.0 && nvm_version_greater 2.0.0 "${NPM_VERSION}"; then + nvm_echo '* `npm` v1.x needs to first jump to `npm` v1.4.28 to be able to upgrade further'; + $NVM_NPM_CMD install -g npm@1.4.28; + else + if nvm_version_greater_than_or_equal_to "${NPM_VERSION}" 2.0.0 && nvm_version_greater 3.0.0 "${NPM_VERSION}"; then + nvm_echo '* `npm` v2.x needs to first jump to the latest v2 to be able to upgrade further'; + $NVM_NPM_CMD install -g npm@2; + fi; + fi; + fi; + fi; + if [ $NVM_IS_0_9 -eq 1 ] || [ $NVM_IS_0_6 -eq 1 ]; then + nvm_echo '* node v0.6 and v0.9 are unable to upgrade further'; + else + if nvm_version_greater 1.1.0 "${NODE_VERSION}"; then + nvm_echo '* `npm` v4.5.x is the last version that works on `node` versions < v1.1.0'; + $NVM_NPM_CMD install -g npm@4.5; + else + if nvm_version_greater 4.0.0 "${NODE_VERSION}"; then + nvm_echo '* `npm` v5 and higher do not work on `node` versions below v4.0.0'; + $NVM_NPM_CMD install -g npm@4; + else + if [ $NVM_IS_0_9 -eq 0 ] && [ $NVM_IS_0_6 -eq 0 ]; then + local NVM_IS_4_4_OR_BELOW; + NVM_IS_4_4_OR_BELOW=0; + if nvm_version_greater 4.5.0 "${NODE_VERSION}"; then + NVM_IS_4_4_OR_BELOW=1; + fi; + local NVM_IS_5_OR_ABOVE; + NVM_IS_5_OR_ABOVE=0; + if [ $NVM_IS_4_4_OR_BELOW -eq 0 ] && nvm_version_greater_than_or_equal_to "${NODE_VERSION}" 5.0.0; then + NVM_IS_5_OR_ABOVE=1; + fi; + local NVM_IS_6_OR_ABOVE; + NVM_IS_6_OR_ABOVE=0; + local NVM_IS_6_2_OR_ABOVE; + NVM_IS_6_2_OR_ABOVE=0; + if [ $NVM_IS_5_OR_ABOVE -eq 1 ] && nvm_version_greater_than_or_equal_to "${NODE_VERSION}" 6.0.0; then + NVM_IS_6_OR_ABOVE=1; + if nvm_version_greater_than_or_equal_to "${NODE_VERSION}" 6.2.0; then + NVM_IS_6_2_OR_ABOVE=1; + fi; + fi; + local NVM_IS_9_OR_ABOVE; + NVM_IS_9_OR_ABOVE=0; + local NVM_IS_9_3_OR_ABOVE; + NVM_IS_9_3_OR_ABOVE=0; + if [ $NVM_IS_6_2_OR_ABOVE -eq 1 ] && nvm_version_greater_than_or_equal_to "${NODE_VERSION}" 9.0.0; then + NVM_IS_9_OR_ABOVE=1; + if nvm_version_greater_than_or_equal_to "${NODE_VERSION}" 9.3.0; then + NVM_IS_9_3_OR_ABOVE=1; + fi; + fi; + local NVM_IS_10_OR_ABOVE; + NVM_IS_10_OR_ABOVE=0; + if [ $NVM_IS_9_3_OR_ABOVE -eq 1 ] && nvm_version_greater_than_or_equal_to "${NODE_VERSION}" 10.0.0; then + NVM_IS_10_OR_ABOVE=1; + fi; + local NVM_IS_12_LTS_OR_ABOVE; + NVM_IS_12_LTS_OR_ABOVE=0; + if [ $NVM_IS_10_OR_ABOVE -eq 1 ] && nvm_version_greater_than_or_equal_to "${NODE_VERSION}" 12.13.0; then + NVM_IS_12_LTS_OR_ABOVE=1; + fi; + local NVM_IS_13_OR_ABOVE; + NVM_IS_13_OR_ABOVE=0; + if [ $NVM_IS_12_LTS_OR_ABOVE -eq 1 ] && nvm_version_greater_than_or_equal_to "${NODE_VERSION}" 13.0.0; then + NVM_IS_13_OR_ABOVE=1; + fi; + local NVM_IS_14_LTS_OR_ABOVE; + NVM_IS_14_LTS_OR_ABOVE=0; + if [ $NVM_IS_13_OR_ABOVE -eq 1 ] && nvm_version_greater_than_or_equal_to "${NODE_VERSION}" 14.15.0; then + NVM_IS_14_LTS_OR_ABOVE=1; + fi; + local NVM_IS_14_17_OR_ABOVE; + NVM_IS_14_17_OR_ABOVE=0; + if [ $NVM_IS_14_LTS_OR_ABOVE -eq 1 ] && nvm_version_greater_than_or_equal_to "${NODE_VERSION}" 14.17.0; then + NVM_IS_14_17_OR_ABOVE=1; + fi; + local NVM_IS_15_OR_ABOVE; + NVM_IS_15_OR_ABOVE=0; + if [ $NVM_IS_14_LTS_OR_ABOVE -eq 1 ] && nvm_version_greater_than_or_equal_to "${NODE_VERSION}" 15.0.0; then + NVM_IS_15_OR_ABOVE=1; + fi; + local NVM_IS_16_OR_ABOVE; + NVM_IS_16_OR_ABOVE=0; + if [ $NVM_IS_15_OR_ABOVE -eq 1 ] && nvm_version_greater_than_or_equal_to "${NODE_VERSION}" 16.0.0; then + NVM_IS_16_OR_ABOVE=1; + fi; + local NVM_IS_16_LTS_OR_ABOVE; + NVM_IS_16_LTS_OR_ABOVE=0; + if [ $NVM_IS_16_OR_ABOVE -eq 1 ] && nvm_version_greater_than_or_equal_to "${NODE_VERSION}" 16.13.0; then + NVM_IS_16_LTS_OR_ABOVE=1; + fi; + local NVM_IS_17_OR_ABOVE; + NVM_IS_17_OR_ABOVE=0; + if [ $NVM_IS_16_LTS_OR_ABOVE -eq 1 ] && nvm_version_greater_than_or_equal_to "${NODE_VERSION}" 17.0.0; then + NVM_IS_17_OR_ABOVE=1; + fi; + local NVM_IS_18_OR_ABOVE; + NVM_IS_18_OR_ABOVE=0; + if [ $NVM_IS_17_OR_ABOVE -eq 1 ] && nvm_version_greater_than_or_equal_to "${NODE_VERSION}" 18.0.0; then + NVM_IS_18_OR_ABOVE=1; + fi; + local NVM_IS_18_17_OR_ABOVE; + NVM_IS_18_17_OR_ABOVE=0; + if [ $NVM_IS_18_OR_ABOVE -eq 1 ] && nvm_version_greater_than_or_equal_to "${NODE_VERSION}" 18.17.0; then + NVM_IS_18_17_OR_ABOVE=1; + fi; + local NVM_IS_19_OR_ABOVE; + NVM_IS_19_OR_ABOVE=0; + if [ $NVM_IS_18_17_OR_ABOVE -eq 1 ] && nvm_version_greater_than_or_equal_to "${NODE_VERSION}" 19.0.0; then + NVM_IS_19_OR_ABOVE=1; + fi; + local NVM_IS_20_5_OR_ABOVE; + NVM_IS_20_5_OR_ABOVE=0; + if [ $NVM_IS_19_OR_ABOVE -eq 1 ] && nvm_version_greater_than_or_equal_to "${NODE_VERSION}" 20.5.0; then + NVM_IS_20_5_OR_ABOVE=1; + fi; + local NVM_IS_20_17_OR_ABOVE; + NVM_IS_20_17_OR_ABOVE=0; + if [ $NVM_IS_20_5_OR_ABOVE -eq 1 ] && nvm_version_greater_than_or_equal_to "${NODE_VERSION}" 20.17.0; then + NVM_IS_20_17_OR_ABOVE=1; + fi; + local NVM_IS_21_OR_ABOVE; + NVM_IS_21_OR_ABOVE=0; + if [ $NVM_IS_20_17_OR_ABOVE -eq 1 ] && nvm_version_greater_than_or_equal_to "${NODE_VERSION}" 21.0.0; then + NVM_IS_21_OR_ABOVE=1; + fi; + local NVM_IS_22_9_OR_ABOVE; + NVM_IS_22_9_OR_ABOVE=0; + if [ $NVM_IS_21_OR_ABOVE -eq 1 ] && nvm_version_greater_than_or_equal_to "${NODE_VERSION}" 22.9.0; then + NVM_IS_22_9_OR_ABOVE=1; + fi; + if [ $NVM_IS_4_4_OR_BELOW -eq 1 ] || { + [ $NVM_IS_5_OR_ABOVE -eq 1 ] && nvm_version_greater 5.10.0 "${NODE_VERSION}" + }; then + nvm_echo '* `npm` `v5.3.x` is the last version that works on `node` 4.x versions below v4.4, or 5.x versions below v5.10, due to `Buffer.alloc`'; + $NVM_NPM_CMD install -g npm@5.3; + else + if [ $NVM_IS_4_4_OR_BELOW -eq 0 ] && nvm_version_greater 4.7.0 "${NODE_VERSION}"; then + nvm_echo '* `npm` `v5.4.1` is the last version that works on `node` `v4.5` and `v4.6`'; + $NVM_NPM_CMD install -g npm@5.4.1; + else + if [ $NVM_IS_6_OR_ABOVE -eq 0 ]; then + nvm_echo '* `npm` `v5.x` is the last version that works on `node` below `v6.0.0`'; + $NVM_NPM_CMD install -g npm@5; + else + if { + [ $NVM_IS_6_OR_ABOVE -eq 1 ] && [ $NVM_IS_6_2_OR_ABOVE -eq 0 ] + } || { + [ $NVM_IS_9_OR_ABOVE -eq 1 ] && [ $NVM_IS_9_3_OR_ABOVE -eq 0 ] + }; then + nvm_echo '* `npm` `v6.9` is the last version that works on `node` `v6.0.x`, `v6.1.x`, `v9.0.x`, `v9.1.x`, or `v9.2.x`'; + $NVM_NPM_CMD install -g npm@6.9; + else + if [ $NVM_IS_10_OR_ABOVE -eq 0 ]; then + if nvm_version_greater 4.4.4 "${NPM_VERSION}"; then + nvm_echo '* `npm` `v4.4.4` or later is required to install npm v6.14.18'; + $NVM_NPM_CMD install -g npm@4; + fi; + nvm_echo '* `npm` `v6.x` is the last version that works on `node` below `v10.0.0`'; + $NVM_NPM_CMD install -g npm@6; + else + if [ $NVM_IS_12_LTS_OR_ABOVE -eq 0 ] || { + [ $NVM_IS_13_OR_ABOVE -eq 1 ] && [ $NVM_IS_14_LTS_OR_ABOVE -eq 0 ] + } || { + [ $NVM_IS_15_OR_ABOVE -eq 1 ] && [ $NVM_IS_16_OR_ABOVE -eq 0 ] + }; then + nvm_echo '* `npm` `v7.x` is the last version that works on `node` `v13`, `v15`, below `v12.13`, or `v14.0` - `v14.15`'; + $NVM_NPM_CMD install -g npm@7; + else + if { + [ $NVM_IS_12_LTS_OR_ABOVE -eq 1 ] && [ $NVM_IS_13_OR_ABOVE -eq 0 ] + } || { + [ $NVM_IS_14_LTS_OR_ABOVE -eq 1 ] && [ $NVM_IS_14_17_OR_ABOVE -eq 0 ] + } || { + [ $NVM_IS_16_OR_ABOVE -eq 1 ] && [ $NVM_IS_16_LTS_OR_ABOVE -eq 0 ] + } || { + [ $NVM_IS_17_OR_ABOVE -eq 1 ] && [ $NVM_IS_18_OR_ABOVE -eq 0 ] + }; then + nvm_echo '* `npm` `v8.6` is the last version that works on `node` `v12`, `v14.13` - `v14.16`, or `v16.0` - `v16.12`'; + $NVM_NPM_CMD install -g npm@8.6; + else + if [ $NVM_IS_18_17_OR_ABOVE -eq 0 ] || { + [ $NVM_IS_19_OR_ABOVE -eq 1 ] && [ $NVM_IS_20_5_OR_ABOVE -eq 0 ] + }; then + nvm_echo '* `npm` `v9.x` is the last version that works on `node` `< v18.17`, `v19`, or `v20.0` - `v20.4`'; + $NVM_NPM_CMD install -g npm@9; + else + if [ $NVM_IS_20_17_OR_ABOVE -eq 0 ] || { + [ $NVM_IS_21_OR_ABOVE -eq 1 ] && [ $NVM_IS_22_9_OR_ABOVE -eq 0 ] + }; then + nvm_echo '* `npm` `v10.x` is the last version that works on `node` `< v20.17`, `v21`, or `v22.0` - `v22.8`'; + $NVM_NPM_CMD install -g npm@10; + else + nvm_echo '* Installing latest `npm`; if this does not work on your node version, please report a bug!'; + $NVM_NPM_CMD install -g npm; + fi; + fi; + fi; + fi; + fi; + fi; + fi; + fi; + fi; + fi; + fi; + fi; + fi; + nvm_echo "* npm upgraded to: v$(npm --version 2> /dev/null)" +} +nvm_install_npm_if_needed () +{ + local VERSION; + VERSION="$(nvm_ls_current)"; + if ! nvm_has "npm"; then + nvm_echo 'Installing npm...'; + if nvm_version_greater 0.2.0 "${VERSION}"; then + nvm_err 'npm requires node v0.2.3 or higher'; + else + if nvm_version_greater_than_or_equal_to "${VERSION}" 0.2.0; then + if nvm_version_greater 0.2.3 "${VERSION}"; then + nvm_err 'npm requires node v0.2.3 or higher'; + else + nvm_download -L https://npmjs.org/install.sh -o - | clean=yes npm_install=0.2.19 sh; + fi; + else + nvm_download -L https://npmjs.org/install.sh -o - | clean=yes sh; + fi; + fi; + fi; + return $? +} +nvm_install_source () +{ + local FLAVOR; + case "${1-}" in + node | iojs) + FLAVOR="${1}" + ;; + *) + nvm_err 'supported flavors: node, iojs'; + return 4 + ;; + esac; + local TYPE; + TYPE="${2-}"; + local PREFIXED_VERSION; + PREFIXED_VERSION="${3-}"; + if [ -z "${PREFIXED_VERSION}" ]; then + nvm_err 'A version number is required.'; + return 3; + fi; + local VERSION; + VERSION="$(nvm_strip_iojs_prefix "${PREFIXED_VERSION}")"; + local NVM_MAKE_JOBS; + NVM_MAKE_JOBS="${4-}"; + local ADDITIONAL_PARAMETERS; + ADDITIONAL_PARAMETERS="${5-}"; + local NVM_ARCH; + NVM_ARCH="$(nvm_get_arch)"; + if [ "${NVM_ARCH}" = 'armv6l' ] || [ "${NVM_ARCH}" = 'armv7l' ]; then + if [ -n "${ADDITIONAL_PARAMETERS}" ]; then + ADDITIONAL_PARAMETERS="--without-snapshot ${ADDITIONAL_PARAMETERS}"; + else + ADDITIONAL_PARAMETERS='--without-snapshot'; + fi; + fi; + if [ -n "${ADDITIONAL_PARAMETERS}" ]; then + nvm_echo "Additional options while compiling: ${ADDITIONAL_PARAMETERS}"; + fi; + local NVM_OS; + NVM_OS="$(nvm_get_os)"; + local make; + make='make'; + local MAKE_CXX; + case "${NVM_OS}" in + 'freebsd' | 'openbsd') + make='gmake'; + MAKE_CXX="CC=${CC:-cc} CXX=${CXX:-c++}" + ;; + 'darwin') + MAKE_CXX="CC=${CC:-cc} CXX=${CXX:-c++}" + ;; + 'aix') + make='gmake' + ;; + esac; + if nvm_has "clang++" && nvm_has "clang" && nvm_version_greater_than_or_equal_to "$(nvm_clang_version)" 3.5; then + if [ -z "${CC-}" ] || [ -z "${CXX-}" ]; then + nvm_echo "Clang v3.5+ detected! CC or CXX not specified, will use Clang as C/C++ compiler!"; + MAKE_CXX="CC=${CC:-cc} CXX=${CXX:-c++}"; + fi; + fi; + local TARBALL; + local TMPDIR; + local VERSION_PATH; + if [ "${NVM_NO_PROGRESS-}" = "1" ]; then + PROGRESS_BAR="-sS"; + else + PROGRESS_BAR="--progress-bar"; + fi; + nvm_is_zsh && setopt local_options shwordsplit; + TARBALL="$(PROGRESS_BAR="${PROGRESS_BAR}" nvm_download_artifact "${FLAVOR}" source "${TYPE}" "${VERSION}" | command tail -1)" && [ -f "${TARBALL}" ] && TMPDIR="$(dirname "${TARBALL}")/files" && if ! ( command mkdir -p "${TMPDIR}" && nvm_extract_tarball "${NVM_OS}" "${VERSION}" "${TARBALL}" "${TMPDIR}" && VERSION_PATH="$(nvm_version_path "${PREFIXED_VERSION}")" && nvm_cd "${TMPDIR}" && nvm_echo '$>'./configure --prefix="${VERSION_PATH}" $ADDITIONAL_PARAMETERS'<' && ./configure --prefix="${VERSION_PATH}" $ADDITIONAL_PARAMETERS && $make -j "${NVM_MAKE_JOBS}" ${MAKE_CXX-} && command rm -f "${VERSION_PATH}" 2> /dev/null && $make -j "${NVM_MAKE_JOBS}" ${MAKE_CXX-} install ); then + nvm_err "nvm: install ${VERSION} failed!"; + command rm -rf "${TMPDIR-}"; + return 1; + fi +} +nvm_iojs_prefix () +{ + nvm_echo 'iojs' +} +nvm_iojs_version_has_solaris_binary () +{ + local IOJS_VERSION; + IOJS_VERSION="$1"; + local STRIPPED_IOJS_VERSION; + STRIPPED_IOJS_VERSION="$(nvm_strip_iojs_prefix "${IOJS_VERSION}")"; + if [ "_${STRIPPED_IOJS_VERSION}" = "${IOJS_VERSION}" ]; then + return 1; + fi; + nvm_version_greater_than_or_equal_to "${STRIPPED_IOJS_VERSION}" v3.3.1 +} +nvm_is_alias () +{ + \alias "${1-}" > /dev/null 2>&1 +} +nvm_is_iojs_version () +{ + case "${1-}" in + iojs-*) + return 0 + ;; + esac; + return 1 +} +nvm_is_merged_node_version () +{ + nvm_version_greater_than_or_equal_to "$1" v4.0.0 +} +nvm_is_natural_num () +{ + if [ -z "$1" ]; then + return 4; + fi; + case "$1" in + 0) + return 1 + ;; + -*) + return 3 + ;; + *) + [ "$1" -eq "$1" ] 2> /dev/null + ;; + esac +} +nvm_is_valid_version () +{ + if nvm_validate_implicit_alias "${1-}" 2> /dev/null; then + return 0; + fi; + case "${1-}" in + "$(nvm_iojs_prefix)" | "$(nvm_node_prefix)") + return 0 + ;; + *) + local VERSION; + VERSION="$(nvm_strip_iojs_prefix "${1-}")"; + nvm_version_greater_than_or_equal_to "${VERSION}" 0 + ;; + esac +} +nvm_is_version_installed () +{ + if [ -z "${1-}" ]; then + return 1; + fi; + local NVM_NODE_BINARY; + NVM_NODE_BINARY='node'; + if [ "_$(nvm_get_os)" = '_win' ]; then + NVM_NODE_BINARY='node.exe'; + fi; + if [ -x "$(nvm_version_path "$1" 2> /dev/null)/bin/${NVM_NODE_BINARY}" ]; then + return 0; + fi; + return 1 +} +nvm_is_zsh () +{ + [ -n "${ZSH_VERSION-}" ] +} +nvm_list_aliases () +{ + local ALIAS; + ALIAS="${1-}"; + local NVM_CURRENT; + NVM_CURRENT="$(nvm_ls_current)"; + local NVM_ALIAS_DIR; + NVM_ALIAS_DIR="$(nvm_alias_path)"; + command mkdir -p "${NVM_ALIAS_DIR}/lts"; + if [ "${ALIAS}" != "${ALIAS#lts/}" ]; then + nvm_alias "${ALIAS}"; + return $?; + fi; + nvm_is_zsh && unsetopt local_options nomatch; + ( local ALIAS_PATH; + for ALIAS_PATH in "${NVM_ALIAS_DIR}/${ALIAS}"*; + do + NVM_NO_COLORS="${NVM_NO_COLORS-}" NVM_CURRENT="${NVM_CURRENT}" nvm_print_alias_path "${NVM_ALIAS_DIR}" "${ALIAS_PATH}" & + done; + wait ) | command sort; + ( local ALIAS_NAME; + for ALIAS_NAME in "$(nvm_node_prefix)" "stable" "unstable" "$(nvm_iojs_prefix)"; + do + { + if [ ! -f "${NVM_ALIAS_DIR}/${ALIAS_NAME}" ] && { + [ -z "${ALIAS}" ] || [ "${ALIAS_NAME}" = "${ALIAS}" ] + }; then + NVM_NO_COLORS="${NVM_NO_COLORS-}" NVM_CURRENT="${NVM_CURRENT}" nvm_print_default_alias "${ALIAS_NAME}"; + fi + } & + done; + wait ) | command sort; + ( local LTS_ALIAS; + for ALIAS_PATH in "${NVM_ALIAS_DIR}/lts/${ALIAS}"*; + do + { + LTS_ALIAS="$(NVM_NO_COLORS="${NVM_NO_COLORS-}" NVM_LTS=true nvm_print_alias_path "${NVM_ALIAS_DIR}" "${ALIAS_PATH}")"; + if [ -n "${LTS_ALIAS}" ]; then + nvm_echo "${LTS_ALIAS}"; + fi + } & + done; + wait ) | command sort; + return +} +nvm_ls () +{ + local PATTERN; + PATTERN="${1-}"; + local VERSIONS; + VERSIONS=''; + if [ "${PATTERN}" = 'current' ]; then + nvm_ls_current; + return; + fi; + local NVM_IOJS_PREFIX; + NVM_IOJS_PREFIX="$(nvm_iojs_prefix)"; + local NVM_NODE_PREFIX; + NVM_NODE_PREFIX="$(nvm_node_prefix)"; + local NVM_VERSION_DIR_IOJS; + NVM_VERSION_DIR_IOJS="$(nvm_version_dir "${NVM_IOJS_PREFIX}")"; + local NVM_VERSION_DIR_NEW; + NVM_VERSION_DIR_NEW="$(nvm_version_dir new)"; + local NVM_VERSION_DIR_OLD; + NVM_VERSION_DIR_OLD="$(nvm_version_dir old)"; + case "${PATTERN}" in + "${NVM_IOJS_PREFIX}" | "${NVM_NODE_PREFIX}") + PATTERN="${PATTERN}-" + ;; + *) + if nvm_resolve_local_alias "${PATTERN}"; then + return; + fi; + PATTERN="$(nvm_ensure_version_prefix "${PATTERN}")" + ;; + esac; + if [ "${PATTERN}" = 'N/A' ]; then + return; + fi; + local NVM_PATTERN_STARTS_WITH_V; + case $PATTERN in + v*) + NVM_PATTERN_STARTS_WITH_V=true + ;; + *) + NVM_PATTERN_STARTS_WITH_V=false + ;; + esac; + if [ $NVM_PATTERN_STARTS_WITH_V = true ] && [ "_$(nvm_num_version_groups "${PATTERN}")" = "_3" ]; then + if nvm_is_version_installed "${PATTERN}"; then + VERSIONS="${PATTERN}"; + else + if nvm_is_version_installed "$(nvm_add_iojs_prefix "${PATTERN}")"; then + VERSIONS="$(nvm_add_iojs_prefix "${PATTERN}")"; + fi; + fi; + else + case "${PATTERN}" in + "${NVM_IOJS_PREFIX}-" | "${NVM_NODE_PREFIX}-" | "system") + + ;; + *) + local NUM_VERSION_GROUPS; + NUM_VERSION_GROUPS="$(nvm_num_version_groups "${PATTERN}")"; + if [ "${NUM_VERSION_GROUPS}" = "2" ] || [ "${NUM_VERSION_GROUPS}" = "1" ]; then + PATTERN="${PATTERN%.}."; + fi + ;; + esac; + nvm_is_zsh && setopt local_options shwordsplit; + nvm_is_zsh && unsetopt local_options markdirs; + local NVM_DIRS_TO_SEARCH1; + NVM_DIRS_TO_SEARCH1=''; + local NVM_DIRS_TO_SEARCH2; + NVM_DIRS_TO_SEARCH2=''; + local NVM_DIRS_TO_SEARCH3; + NVM_DIRS_TO_SEARCH3=''; + local NVM_ADD_SYSTEM; + NVM_ADD_SYSTEM=false; + if nvm_is_iojs_version "${PATTERN}"; then + NVM_DIRS_TO_SEARCH1="${NVM_VERSION_DIR_IOJS}"; + PATTERN="$(nvm_strip_iojs_prefix "${PATTERN}")"; + if nvm_has_system_iojs; then + NVM_ADD_SYSTEM=true; + fi; + else + if [ "${PATTERN}" = "${NVM_NODE_PREFIX}-" ]; then + NVM_DIRS_TO_SEARCH1="${NVM_VERSION_DIR_OLD}"; + NVM_DIRS_TO_SEARCH2="${NVM_VERSION_DIR_NEW}"; + PATTERN=''; + if nvm_has_system_node; then + NVM_ADD_SYSTEM=true; + fi; + else + NVM_DIRS_TO_SEARCH1="${NVM_VERSION_DIR_OLD}"; + NVM_DIRS_TO_SEARCH2="${NVM_VERSION_DIR_NEW}"; + NVM_DIRS_TO_SEARCH3="${NVM_VERSION_DIR_IOJS}"; + if nvm_has_system_iojs || nvm_has_system_node; then + NVM_ADD_SYSTEM=true; + fi; + fi; + fi; + if ! [ -d "${NVM_DIRS_TO_SEARCH1}" ] || ! ( command ls -1qA "${NVM_DIRS_TO_SEARCH1}" | nvm_grep -q . ); then + NVM_DIRS_TO_SEARCH1=''; + fi; + if ! [ -d "${NVM_DIRS_TO_SEARCH2}" ] || ! ( command ls -1qA "${NVM_DIRS_TO_SEARCH2}" | nvm_grep -q . ); then + NVM_DIRS_TO_SEARCH2="${NVM_DIRS_TO_SEARCH1}"; + fi; + if ! [ -d "${NVM_DIRS_TO_SEARCH3}" ] || ! ( command ls -1qA "${NVM_DIRS_TO_SEARCH3}" | nvm_grep -q . ); then + NVM_DIRS_TO_SEARCH3="${NVM_DIRS_TO_SEARCH2}"; + fi; + local SEARCH_PATTERN; + if [ -z "${PATTERN}" ]; then + PATTERN='v'; + SEARCH_PATTERN='.*'; + else + SEARCH_PATTERN="$(nvm_echo "${PATTERN}" | command sed 's#\.#\\\.#g;')"; + fi; + if [ -n "${NVM_DIRS_TO_SEARCH1}${NVM_DIRS_TO_SEARCH2}${NVM_DIRS_TO_SEARCH3}" ]; then + VERSIONS="$(command find "${NVM_DIRS_TO_SEARCH1}"/* "${NVM_DIRS_TO_SEARCH2}"/* "${NVM_DIRS_TO_SEARCH3}"/* -name . -o -type d -prune -o -path "${PATTERN}*" | command sed -e " + s#${NVM_VERSION_DIR_IOJS}/#versions/${NVM_IOJS_PREFIX}/#; + s#^${NVM_DIR}/##; + \\#^[^v]# d; + \\#^versions\$# d; + s#^versions/##; + s#^v#${NVM_NODE_PREFIX}/v#; + \\#${SEARCH_PATTERN}# !d; + " -e 's#^\([^/]\{1,\}\)/\(.*\)$#\2.\1#;' | command sort -t. -u -k 1.2,1n -k 2,2n -k 3,3n | command sed -e 's#\(.*\)\.\([^\.]\{1,\}\)$#\2-\1#;' -e "s#^${NVM_NODE_PREFIX}-##;")"; + fi; + fi; + if [ "${NVM_ADD_SYSTEM-}" = true ]; then + case "${PATTERN}" in + '' | v) + VERSIONS="${VERSIONS} +system" + ;; + system) + VERSIONS="system" + ;; + esac; + fi; + if [ -z "${VERSIONS}" ]; then + nvm_echo 'N/A'; + return 3; + fi; + nvm_echo "${VERSIONS}" +} +nvm_ls_current () +{ + local NVM_LS_CURRENT_NODE_PATH; + if ! NVM_LS_CURRENT_NODE_PATH="$(command which node 2> /dev/null)"; then + nvm_echo 'none'; + else + if nvm_tree_contains_path "$(nvm_version_dir iojs)" "${NVM_LS_CURRENT_NODE_PATH}"; then + nvm_add_iojs_prefix "$(iojs --version 2> /dev/null)"; + else + if nvm_tree_contains_path "${NVM_DIR}" "${NVM_LS_CURRENT_NODE_PATH}"; then + local VERSION; + VERSION="$(node --version 2> /dev/null)"; + if [ "${VERSION}" = "v0.6.21-pre" ]; then + nvm_echo 'v0.6.21'; + else + nvm_echo "${VERSION:-none}"; + fi; + else + nvm_echo 'system'; + fi; + fi; + fi +} +nvm_ls_remote () +{ + local PATTERN; + PATTERN="${1-}"; + if nvm_validate_implicit_alias "${PATTERN}" 2> /dev/null; then + local IMPLICIT; + IMPLICIT="$(nvm_print_implicit_alias remote "${PATTERN}")"; + if [ -z "${IMPLICIT-}" ] || [ "${IMPLICIT}" = 'N/A' ]; then + nvm_echo "N/A"; + return 3; + fi; + PATTERN="$(NVM_LTS="${NVM_LTS-}" nvm_ls_remote "${IMPLICIT}" | command tail -1 | command awk '{ print $1 }')"; + else + if [ -n "${PATTERN}" ]; then + PATTERN="$(nvm_ensure_version_prefix "${PATTERN}")"; + else + PATTERN=".*"; + fi; + fi; + NVM_LTS="${NVM_LTS-}" nvm_ls_remote_index_tab node std "${PATTERN}" +} +nvm_ls_remote_index_tab () +{ + local LTS; + LTS="${NVM_LTS-}"; + if [ "$#" -lt 3 ]; then + nvm_err 'not enough arguments'; + return 5; + fi; + local FLAVOR; + FLAVOR="${1-}"; + local TYPE; + TYPE="${2-}"; + local MIRROR; + MIRROR="$(nvm_get_mirror "${FLAVOR}" "${TYPE}")"; + if [ -z "${MIRROR}" ]; then + return 3; + fi; + local PREFIX; + PREFIX=''; + case "${FLAVOR}-${TYPE}" in + iojs-std) + PREFIX="$(nvm_iojs_prefix)-" + ;; + node-std) + PREFIX='' + ;; + iojs-*) + nvm_err 'unknown type of io.js release'; + return 4 + ;; + *) + nvm_err 'unknown type of node.js release'; + return 4 + ;; + esac; + local SORT_COMMAND; + SORT_COMMAND='command sort'; + case "${FLAVOR}" in + node) + SORT_COMMAND='command sort -t. -u -k 1.2,1n -k 2,2n -k 3,3n' + ;; + esac; + local PATTERN; + PATTERN="${3-}"; + if [ "${PATTERN#"${PATTERN%?}"}" = '.' ]; then + PATTERN="${PATTERN%.}"; + fi; + local VERSIONS; + if [ -n "${PATTERN}" ] && [ "${PATTERN}" != '*' ]; then + if [ "${FLAVOR}" = 'iojs' ]; then + PATTERN="$(nvm_ensure_version_prefix "$(nvm_strip_iojs_prefix "${PATTERN}")")"; + else + PATTERN="$(nvm_ensure_version_prefix "${PATTERN}")"; + fi; + else + unset PATTERN; + fi; + nvm_is_zsh && setopt local_options shwordsplit; + local VERSION_LIST; + VERSION_LIST="$(nvm_download -L -s "${MIRROR}/index.tab" -o - | command sed " + 1d; + s/^/${PREFIX}/; + ")"; + local LTS_ALIAS; + local LTS_VERSION; + command mkdir -p "$(nvm_alias_path)/lts"; + { + command awk '{ + if ($10 ~ /^\-?$/) { next } + if ($10 && !a[tolower($10)]++) { + if (alias) { print alias, version } + alias_name = "lts/" tolower($10) + if (!alias) { print "lts/*", alias_name } + alias = alias_name + version = $1 + } + } + END { + if (alias) { + print alias, version + } + }' | while read -r LTS_ALIAS_LINE; do + LTS_ALIAS="${LTS_ALIAS_LINE%% *}"; + LTS_VERSION="${LTS_ALIAS_LINE#* }"; + nvm_make_alias "${LTS_ALIAS}" "${LTS_VERSION}" > /dev/null 2>&1; + done + } < /dev/null +} +nvm_match_version () +{ + local NVM_IOJS_PREFIX; + NVM_IOJS_PREFIX="$(nvm_iojs_prefix)"; + local PROVIDED_VERSION; + PROVIDED_VERSION="$1"; + case "_${PROVIDED_VERSION}" in + "_${NVM_IOJS_PREFIX}" | '_io.js') + nvm_version "${NVM_IOJS_PREFIX}" + ;; + '_system') + nvm_echo 'system' + ;; + *) + nvm_version "${PROVIDED_VERSION}" + ;; + esac +} +nvm_node_prefix () +{ + nvm_echo 'node' +} +nvm_node_version_has_solaris_binary () +{ + local NODE_VERSION; + NODE_VERSION="$1"; + local STRIPPED_IOJS_VERSION; + STRIPPED_IOJS_VERSION="$(nvm_strip_iojs_prefix "${NODE_VERSION}")"; + if [ "_${STRIPPED_IOJS_VERSION}" != "_${NODE_VERSION}" ]; then + return 1; + fi; + nvm_version_greater_than_or_equal_to "${NODE_VERSION}" v0.8.6 && ! nvm_version_greater_than_or_equal_to "${NODE_VERSION}" v1.0.0 +} +nvm_normalize_lts () +{ + local LTS; + LTS="${1-}"; + case "${LTS}" in + lts/-[123456789] | lts/-[123456789][0123456789]*) + local N; + N="$(echo "${LTS}" | cut -d '-' -f 2)"; + N=$((N+1)); + if [ $? -ne 0 ]; then + nvm_echo "${LTS}"; + return 0; + fi; + local NVM_ALIAS_DIR; + NVM_ALIAS_DIR="$(nvm_alias_path)"; + local RESULT; + RESULT="$(command ls "${NVM_ALIAS_DIR}/lts" | command tail -n "${N}" | command head -n 1)"; + if [ "${RESULT}" != '*' ]; then + nvm_echo "lts/${RESULT}"; + else + nvm_err 'That many LTS releases do not exist yet.'; + return 2; + fi + ;; + *) + if [ "${LTS}" != "$(echo "${LTS}" | command tr '[:upper:]' '[:lower:]')" ]; then + nvm_err 'LTS names must be lowercase'; + return 3; + fi; + nvm_echo "${LTS}" + ;; + esac +} +nvm_normalize_version () +{ + command awk 'BEGIN { + split(ARGV[1], a, /\./); + printf "%d%06d%06d\n", a[1], a[2], a[3]; + exit; + }' "${1#v}" +} +nvm_npm_global_modules () +{ + local NPMLIST; + local VERSION; + VERSION="$1"; + NPMLIST=$(nvm use "${VERSION}" > /dev/null && npm list -g --depth=0 2> /dev/null | command sed -e '1d' -e '/UNMET PEER DEPENDENCY/d'); + local INSTALLS; + INSTALLS=$(nvm_echo "${NPMLIST}" | command sed -e '/ -> / d' -e '/\(empty\)/ d' -e 's/^.* \(.*@[^ ]*\).*/\1/' -e '/^npm@[^ ]*.*$/ d' -e '/^corepack@[^ ]*.*$/ d' | command xargs); + local LINKS; + LINKS="$(nvm_echo "${NPMLIST}" | command sed -n 's/.* -> \(.*\)/\1/ p')"; + nvm_echo "${INSTALLS} //// ${LINKS}" +} +nvm_npmrc_bad_news_bears () +{ + local NVM_NPMRC; + NVM_NPMRC="${1-}"; + if [ -n "${NVM_NPMRC}" ] && [ -f "${NVM_NPMRC}" ] && nvm_grep -Ee '^(prefix|globalconfig) *=' < "${NVM_NPMRC}" > /dev/null; then + return 0; + fi; + return 1 +} +nvm_num_version_groups () +{ + local VERSION; + VERSION="${1-}"; + VERSION="${VERSION#v}"; + VERSION="${VERSION%.}"; + if [ -z "${VERSION}" ]; then + nvm_echo "0"; + return; + fi; + local NVM_NUM_DOTS; + NVM_NUM_DOTS=$(nvm_echo "${VERSION}" | command sed -e 's/[^\.]//g'); + local NVM_NUM_GROUPS; + NVM_NUM_GROUPS=".${NVM_NUM_DOTS}"; + nvm_echo "${#NVM_NUM_GROUPS}" +} +nvm_nvmrc_invalid_msg () +{ + local error_text; + error_text="invalid .nvmrc! +all non-commented content (anything after # is a comment) must be either: + - a single bare nvm-recognized version-ish + - or, multiple distinct key-value pairs, each key/value separated by a single equals sign (=) + +additionally, a single bare nvm-recognized version-ish must be present (after stripping comments)."; + local warn_text; + warn_text="non-commented content parsed: +${1}"; + nvm_err "$(nvm_wrap_with_color_code 'r' "${error_text}") + +$(nvm_wrap_with_color_code 'y' "${warn_text}")" +} +nvm_print_alias_path () +{ + local NVM_ALIAS_DIR; + NVM_ALIAS_DIR="${1-}"; + if [ -z "${NVM_ALIAS_DIR}" ]; then + nvm_err 'An alias dir is required.'; + return 1; + fi; + local ALIAS_PATH; + ALIAS_PATH="${2-}"; + if [ -z "${ALIAS_PATH}" ]; then + nvm_err 'An alias path is required.'; + return 2; + fi; + local ALIAS; + ALIAS="${ALIAS_PATH##"${NVM_ALIAS_DIR}"\/}"; + local DEST; + DEST="$(nvm_alias "${ALIAS}" 2> /dev/null)" || :; + if [ -n "${DEST}" ]; then + NVM_NO_COLORS="${NVM_NO_COLORS-}" NVM_LTS="${NVM_LTS-}" DEFAULT=false nvm_print_formatted_alias "${ALIAS}" "${DEST}"; + fi +} +nvm_print_color_code () +{ + case "${1-}" in + '0') + return 0 + ;; + 'r') + nvm_echo '0;31m' + ;; + 'R') + nvm_echo '1;31m' + ;; + 'g') + nvm_echo '0;32m' + ;; + 'G') + nvm_echo '1;32m' + ;; + 'b') + nvm_echo '0;34m' + ;; + 'B') + nvm_echo '1;34m' + ;; + 'c') + nvm_echo '0;36m' + ;; + 'C') + nvm_echo '1;36m' + ;; + 'm') + nvm_echo '0;35m' + ;; + 'M') + nvm_echo '1;35m' + ;; + 'y') + nvm_echo '0;33m' + ;; + 'Y') + nvm_echo '1;33m' + ;; + 'k') + nvm_echo '0;30m' + ;; + 'K') + nvm_echo '1;30m' + ;; + 'e') + nvm_echo '0;37m' + ;; + 'W') + nvm_echo '1;37m' + ;; + *) + nvm_err "Invalid color code: ${1-}"; + return 1 + ;; + esac +} +nvm_print_default_alias () +{ + local ALIAS; + ALIAS="${1-}"; + if [ -z "${ALIAS}" ]; then + nvm_err 'A default alias is required.'; + return 1; + fi; + local DEST; + DEST="$(nvm_print_implicit_alias local "${ALIAS}")"; + if [ -n "${DEST}" ]; then + NVM_NO_COLORS="${NVM_NO_COLORS-}" DEFAULT=true nvm_print_formatted_alias "${ALIAS}" "${DEST}"; + fi +} +nvm_print_formatted_alias () +{ + local ALIAS; + ALIAS="${1-}"; + local DEST; + DEST="${2-}"; + local VERSION; + VERSION="${3-}"; + if [ -z "${VERSION}" ]; then + VERSION="$(nvm_version "${DEST}")" || :; + fi; + local VERSION_FORMAT; + local ALIAS_FORMAT; + local DEST_FORMAT; + local INSTALLED_COLOR; + local SYSTEM_COLOR; + local CURRENT_COLOR; + local NOT_INSTALLED_COLOR; + local DEFAULT_COLOR; + local LTS_COLOR; + INSTALLED_COLOR=$(nvm_get_colors 1); + SYSTEM_COLOR=$(nvm_get_colors 2); + CURRENT_COLOR=$(nvm_get_colors 3); + NOT_INSTALLED_COLOR=$(nvm_get_colors 4); + DEFAULT_COLOR=$(nvm_get_colors 5); + LTS_COLOR=$(nvm_get_colors 6); + ALIAS_FORMAT='%s'; + DEST_FORMAT='%s'; + VERSION_FORMAT='%s'; + local NEWLINE; + NEWLINE='\n'; + if [ "_${DEFAULT}" = '_true' ]; then + NEWLINE=' (default)\n'; + fi; + local ARROW; + ARROW='->'; + if nvm_has_colors; then + ARROW='\033[0;90m->\033[0m'; + if [ "_${DEFAULT}" = '_true' ]; then + NEWLINE=" \033[${DEFAULT_COLOR}(default)\033[0m\n"; + fi; + if [ "_${VERSION}" = "_${NVM_CURRENT-}" ]; then + ALIAS_FORMAT="\033[${CURRENT_COLOR}%s\033[0m"; + DEST_FORMAT="\033[${CURRENT_COLOR}%s\033[0m"; + VERSION_FORMAT="\033[${CURRENT_COLOR}%s\033[0m"; + else + if nvm_is_version_installed "${VERSION}"; then + ALIAS_FORMAT="\033[${INSTALLED_COLOR}%s\033[0m"; + DEST_FORMAT="\033[${INSTALLED_COLOR}%s\033[0m"; + VERSION_FORMAT="\033[${INSTALLED_COLOR}%s\033[0m"; + else + if [ "${VERSION}" = '∞' ] || [ "${VERSION}" = 'N/A' ]; then + ALIAS_FORMAT="\033[${NOT_INSTALLED_COLOR}%s\033[0m"; + DEST_FORMAT="\033[${NOT_INSTALLED_COLOR}%s\033[0m"; + VERSION_FORMAT="\033[${NOT_INSTALLED_COLOR}%s\033[0m"; + fi; + fi; + fi; + if [ "_${NVM_LTS-}" = '_true' ]; then + ALIAS_FORMAT="\033[${LTS_COLOR}%s\033[0m"; + fi; + if [ "_${DEST%/*}" = "_lts" ]; then + DEST_FORMAT="\033[${LTS_COLOR}%s\033[0m"; + fi; + else + if [ "_${VERSION}" != '_∞' ] && [ "_${VERSION}" != '_N/A' ]; then + VERSION_FORMAT='%s *'; + fi; + fi; + if [ "${DEST}" = "${VERSION}" ]; then + command printf -- "${ALIAS_FORMAT} ${ARROW} ${VERSION_FORMAT}${NEWLINE}" "${ALIAS}" "${DEST}"; + else + command printf -- "${ALIAS_FORMAT} ${ARROW} ${DEST_FORMAT} (${ARROW} ${VERSION_FORMAT})${NEWLINE}" "${ALIAS}" "${DEST}" "${VERSION}"; + fi +} +nvm_print_implicit_alias () +{ + if [ "_$1" != "_local" ] && [ "_$1" != "_remote" ]; then + nvm_err "nvm_print_implicit_alias must be specified with local or remote as the first argument."; + return 1; + fi; + local NVM_IMPLICIT; + NVM_IMPLICIT="$2"; + if ! nvm_validate_implicit_alias "${NVM_IMPLICIT}"; then + return 2; + fi; + local NVM_IOJS_PREFIX; + NVM_IOJS_PREFIX="$(nvm_iojs_prefix)"; + local NVM_NODE_PREFIX; + NVM_NODE_PREFIX="$(nvm_node_prefix)"; + local NVM_COMMAND; + local NVM_ADD_PREFIX_COMMAND; + local LAST_TWO; + case "${NVM_IMPLICIT}" in + "${NVM_IOJS_PREFIX}") + NVM_COMMAND="nvm_ls_remote_iojs"; + NVM_ADD_PREFIX_COMMAND="nvm_add_iojs_prefix"; + if [ "_$1" = "_local" ]; then + NVM_COMMAND="nvm_ls ${NVM_IMPLICIT}"; + fi; + nvm_is_zsh && setopt local_options shwordsplit; + local NVM_IOJS_VERSION; + local EXIT_CODE; + NVM_IOJS_VERSION="$(${NVM_COMMAND})" && :; + EXIT_CODE="$?"; + if [ "_${EXIT_CODE}" = "_0" ]; then + NVM_IOJS_VERSION="$(nvm_echo "${NVM_IOJS_VERSION}" | command sed "s/^${NVM_IMPLICIT}-//" | nvm_grep -e '^v' | command cut -c2- | command cut -d . -f 1,2 | uniq | command tail -1)"; + fi; + if [ "_$NVM_IOJS_VERSION" = "_N/A" ]; then + nvm_echo 'N/A'; + else + ${NVM_ADD_PREFIX_COMMAND} "${NVM_IOJS_VERSION}"; + fi; + return $EXIT_CODE + ;; + "${NVM_NODE_PREFIX}") + nvm_echo 'stable'; + return + ;; + *) + NVM_COMMAND="nvm_ls_remote"; + if [ "_$1" = "_local" ]; then + NVM_COMMAND="nvm_ls node"; + fi; + nvm_is_zsh && setopt local_options shwordsplit; + LAST_TWO=$($NVM_COMMAND | nvm_grep -e '^v' | command cut -c2- | command cut -d . -f 1,2 | uniq) + ;; + esac; + local MINOR; + local STABLE; + local UNSTABLE; + local MOD; + local NORMALIZED_VERSION; + nvm_is_zsh && setopt local_options shwordsplit; + for MINOR in $LAST_TWO; + do + NORMALIZED_VERSION="$(nvm_normalize_version "$MINOR")"; + if [ "_0${NORMALIZED_VERSION#?}" != "_$NORMALIZED_VERSION" ]; then + STABLE="$MINOR"; + else + MOD="$(awk 'BEGIN { print int(ARGV[1] / 1000000) % 2 ; exit(0) }' "${NORMALIZED_VERSION}")"; + if [ "${MOD}" -eq 0 ]; then + STABLE="${MINOR}"; + else + if [ "${MOD}" -eq 1 ]; then + UNSTABLE="${MINOR}"; + fi; + fi; + fi; + done; + if [ "_$2" = '_stable' ]; then + nvm_echo "${STABLE}"; + else + if [ "_$2" = '_unstable' ]; then + nvm_echo "${UNSTABLE:-"N/A"}"; + fi; + fi +} +nvm_print_npm_version () +{ + if nvm_has "npm"; then + local NPM_VERSION; + NPM_VERSION="$(npm --version 2> /dev/null)"; + if [ -n "${NPM_VERSION}" ]; then + command printf " (npm v${NPM_VERSION})"; + fi; + fi +} +nvm_print_versions () +{ + local NVM_CURRENT; + NVM_CURRENT=$(nvm_ls_current); + local INSTALLED_COLOR; + local SYSTEM_COLOR; + local CURRENT_COLOR; + local NOT_INSTALLED_COLOR; + local DEFAULT_COLOR; + local LTS_COLOR; + local NVM_HAS_COLORS; + NVM_HAS_COLORS=0; + INSTALLED_COLOR=$(nvm_get_colors 1); + SYSTEM_COLOR=$(nvm_get_colors 2); + CURRENT_COLOR=$(nvm_get_colors 3); + NOT_INSTALLED_COLOR=$(nvm_get_colors 4); + DEFAULT_COLOR=$(nvm_get_colors 5); + LTS_COLOR=$(nvm_get_colors 6); + if nvm_has_colors; then + NVM_HAS_COLORS=1; + fi; + command awk -v remote_versions="$(printf '%s' "${1-}" | tr '\n' '|')" -v installed_versions="$(nvm_ls | tr '\n' '|')" -v current="$NVM_CURRENT" -v installed_color="$INSTALLED_COLOR" -v system_color="$SYSTEM_COLOR" -v current_color="$CURRENT_COLOR" -v default_color="$DEFAULT_COLOR" -v old_lts_color="$DEFAULT_COLOR" -v has_colors="$NVM_HAS_COLORS" ' +function alen(arr, i, len) { len=0; for(i in arr) len++; return len; } +BEGIN { + fmt_installed = has_colors ? (installed_color ? "\033[" installed_color "%15s\033[0m" : "%15s") : "%15s *"; + fmt_system = has_colors ? (system_color ? "\033[" system_color "%15s\033[0m" : "%15s") : "%15s *"; + fmt_current = has_colors ? (current_color ? "\033[" current_color "->%13s\033[0m" : "%15s") : "->%13s *"; + + latest_lts_color = current_color; + sub(/0;/, "1;", latest_lts_color); + + fmt_latest_lts = has_colors && latest_lts_color ? ("\033[" latest_lts_color " (Latest LTS: %s)\033[0m") : " (Latest LTS: %s)"; + fmt_old_lts = has_colors && old_lts_color ? ("\033[" old_lts_color " (LTS: %s)\033[0m") : " (LTS: %s)"; + + split(remote_versions, lines, "|"); + split(installed_versions, installed, "|"); + rows = alen(lines); + + for (n = 1; n <= rows; n++) { + split(lines[n], fields, "[[:blank:]]+"); + cols = alen(fields); + version = fields[1]; + is_installed = 0; + + for (i in installed) { + if (version == installed[i]) { + is_installed = 1; + break; + } + } + + fmt_version = "%15s"; + if (version == current) { + fmt_version = fmt_current; + } else if (version == "system") { + fmt_version = fmt_system; + } else if (is_installed) { + fmt_version = fmt_installed; + } + + padding = (!has_colors && is_installed) ? "" : " "; + + if (cols == 1) { + formatted = sprintf(fmt_version, version); + } else if (cols == 2) { + formatted = sprintf((fmt_version padding fmt_old_lts), version, fields[2]); + } else if (cols == 3 && fields[3] == "*") { + formatted = sprintf((fmt_version padding fmt_latest_lts), version, fields[2]); + } + + output[n] = formatted; + } + + for (n = 1; n <= rows; n++) { + print output[n] + } + + exit +}' +} +nvm_process_nvmrc () +{ + local NVMRC_PATH; + NVMRC_PATH="$1"; + local lines; + lines=$(command sed 's/#.*//' "$NVMRC_PATH" | command sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | nvm_grep -v '^$'); + if [ -z "$lines" ]; then + nvm_nvmrc_invalid_msg "${lines}"; + return 1; + fi; + local keys; + keys=''; + local values; + values=''; + local unpaired_line; + unpaired_line=''; + while IFS= read -r line; do + if [ -z "${line}" ]; then + continue; + else + if [ -z "${line%%=*}" ]; then + if [ -n "${unpaired_line}" ]; then + nvm_nvmrc_invalid_msg "${lines}"; + return 1; + fi; + unpaired_line="${line}"; + else + if case "$line" in + *'='*) + true + ;; + *) + false + ;; + esac; then + key="${line%%=*}"; + value="${line#*=}"; + key=$(nvm_echo "${key}" | command sed 's/^[[:space:]]*//;s/[[:space:]]*$//'); + value=$(nvm_echo "${value}" | command sed 's/^[[:space:]]*//;s/[[:space:]]*$//'); + if [ "${key}" = 'node' ]; then + nvm_nvmrc_invalid_msg "${lines}"; + return 1; + fi; + if nvm_echo "${keys}" | nvm_grep -q -E "(^| )${key}( |$)"; then + nvm_nvmrc_invalid_msg "${lines}"; + return 1; + fi; + keys="${keys} ${key}"; + values="${values} ${value}"; + else + if [ -n "${unpaired_line}" ]; then + nvm_nvmrc_invalid_msg "${lines}"; + return 1; + fi; + unpaired_line="${line}"; + fi; + fi; + fi; + done <"; + fi +} +nvm_remote_version () +{ + local PATTERN; + PATTERN="${1-}"; + local VERSION; + if nvm_validate_implicit_alias "${PATTERN}" 2> /dev/null; then + case "${PATTERN}" in + "$(nvm_iojs_prefix)") + VERSION="$(NVM_LTS="${NVM_LTS-}" nvm_ls_remote_iojs | command tail -1)" && : + ;; + *) + VERSION="$(NVM_LTS="${NVM_LTS-}" nvm_ls_remote "${PATTERN}")" && : + ;; + esac; + else + VERSION="$(NVM_LTS="${NVM_LTS-}" nvm_remote_versions "${PATTERN}" | command tail -1)"; + fi; + if [ -n "${NVM_VERSION_ONLY-}" ]; then + command awk 'BEGIN { + n = split(ARGV[1], a); + print a[1] + }' "${VERSION}"; + else + nvm_echo "${VERSION}"; + fi; + if [ "${VERSION}" = 'N/A' ]; then + return 3; + fi +} +nvm_remote_versions () +{ + local NVM_IOJS_PREFIX; + NVM_IOJS_PREFIX="$(nvm_iojs_prefix)"; + local NVM_NODE_PREFIX; + NVM_NODE_PREFIX="$(nvm_node_prefix)"; + local PATTERN; + PATTERN="${1-}"; + local NVM_FLAVOR; + if [ -n "${NVM_LTS-}" ]; then + NVM_FLAVOR="${NVM_NODE_PREFIX}"; + fi; + case "${PATTERN}" in + "${NVM_IOJS_PREFIX}" | "io.js") + NVM_FLAVOR="${NVM_IOJS_PREFIX}"; + unset PATTERN + ;; + "${NVM_NODE_PREFIX}") + NVM_FLAVOR="${NVM_NODE_PREFIX}"; + unset PATTERN + ;; + esac; + if nvm_validate_implicit_alias "${PATTERN-}" 2> /dev/null; then + nvm_err 'Implicit aliases are not supported in nvm_remote_versions.'; + return 1; + fi; + local NVM_LS_REMOTE_EXIT_CODE; + NVM_LS_REMOTE_EXIT_CODE=0; + local NVM_LS_REMOTE_PRE_MERGED_OUTPUT; + NVM_LS_REMOTE_PRE_MERGED_OUTPUT=''; + local NVM_LS_REMOTE_POST_MERGED_OUTPUT; + NVM_LS_REMOTE_POST_MERGED_OUTPUT=''; + if [ -z "${NVM_FLAVOR-}" ] || [ "${NVM_FLAVOR-}" = "${NVM_NODE_PREFIX}" ]; then + local NVM_LS_REMOTE_OUTPUT; + NVM_LS_REMOTE_OUTPUT="$(NVM_LTS="${NVM_LTS-}" nvm_ls_remote "${PATTERN-}") " && :; + NVM_LS_REMOTE_EXIT_CODE=$?; + NVM_LS_REMOTE_PRE_MERGED_OUTPUT="${NVM_LS_REMOTE_OUTPUT%%v4\.0\.0*}"; + NVM_LS_REMOTE_POST_MERGED_OUTPUT="${NVM_LS_REMOTE_OUTPUT#"$NVM_LS_REMOTE_PRE_MERGED_OUTPUT"}"; + fi; + local NVM_LS_REMOTE_IOJS_EXIT_CODE; + NVM_LS_REMOTE_IOJS_EXIT_CODE=0; + local NVM_LS_REMOTE_IOJS_OUTPUT; + NVM_LS_REMOTE_IOJS_OUTPUT=''; + if [ -z "${NVM_LTS-}" ] && { + [ -z "${NVM_FLAVOR-}" ] || [ "${NVM_FLAVOR-}" = "${NVM_IOJS_PREFIX}" ] + }; then + NVM_LS_REMOTE_IOJS_OUTPUT=$(nvm_ls_remote_iojs "${PATTERN-}") && :; + NVM_LS_REMOTE_IOJS_EXIT_CODE=$?; + fi; + VERSIONS="$(nvm_echo "${NVM_LS_REMOTE_PRE_MERGED_OUTPUT} +${NVM_LS_REMOTE_IOJS_OUTPUT} +${NVM_LS_REMOTE_POST_MERGED_OUTPUT}" | nvm_grep -v "N/A" | command sed '/^ *$/d')"; + if [ -z "${VERSIONS}" ]; then + nvm_echo 'N/A'; + return 3; + fi; + nvm_echo "${VERSIONS}" | command sed 's/ *$//g'; + return $NVM_LS_REMOTE_EXIT_CODE || $NVM_LS_REMOTE_IOJS_EXIT_CODE +} +nvm_resolve_alias () +{ + if [ -z "${1-}" ]; then + return 1; + fi; + local PATTERN; + PATTERN="${1-}"; + local ALIAS; + ALIAS="${PATTERN}"; + local ALIAS_TEMP; + local SEEN_ALIASES; + SEEN_ALIASES="${ALIAS}"; + local NVM_ALIAS_INDEX; + NVM_ALIAS_INDEX=1; + while true; do + ALIAS_TEMP="$( ( nvm_alias "${ALIAS}" 2> /dev/null | command head -n "${NVM_ALIAS_INDEX}" | command tail -n 1 ) || nvm_echo)"; + if [ -z "${ALIAS_TEMP}" ]; then + break; + fi; + if command printf "${SEEN_ALIASES}" | nvm_grep -q -e "^${ALIAS_TEMP}$"; then + ALIAS="∞"; + break; + fi; + SEEN_ALIASES="${SEEN_ALIASES}\\n${ALIAS_TEMP}"; + ALIAS="${ALIAS_TEMP}"; + done; + if [ -n "${ALIAS}" ] && [ "_${ALIAS}" != "_${PATTERN}" ]; then + local NVM_IOJS_PREFIX; + NVM_IOJS_PREFIX="$(nvm_iojs_prefix)"; + local NVM_NODE_PREFIX; + NVM_NODE_PREFIX="$(nvm_node_prefix)"; + case "${ALIAS}" in + '∞' | "${NVM_IOJS_PREFIX}" | "${NVM_IOJS_PREFIX}-" | "${NVM_NODE_PREFIX}") + nvm_echo "${ALIAS}" + ;; + *) + nvm_ensure_version_prefix "${ALIAS}" + ;; + esac; + return 0; + fi; + if nvm_validate_implicit_alias "${PATTERN}" 2> /dev/null; then + local IMPLICIT; + IMPLICIT="$(nvm_print_implicit_alias local "${PATTERN}" 2> /dev/null)"; + if [ -n "${IMPLICIT}" ]; then + nvm_ensure_version_prefix "${IMPLICIT}"; + fi; + fi; + return 2 +} +nvm_resolve_local_alias () +{ + if [ -z "${1-}" ]; then + return 1; + fi; + local VERSION; + local EXIT_CODE; + VERSION="$(nvm_resolve_alias "${1-}")"; + EXIT_CODE=$?; + if [ -z "${VERSION}" ]; then + return $EXIT_CODE; + fi; + if [ "_${VERSION}" != '_∞' ]; then + nvm_version "${VERSION}"; + else + nvm_echo "${VERSION}"; + fi +} +nvm_sanitize_auth_header () +{ + nvm_echo "$1" | command sed 's/[^a-zA-Z0-9:;_. -]//g' +} +nvm_sanitize_path () +{ + local SANITIZED_PATH; + SANITIZED_PATH="${1-}"; + if [ "_${SANITIZED_PATH}" != "_${NVM_DIR}" ]; then + SANITIZED_PATH="$(nvm_echo "${SANITIZED_PATH}" | command sed -e "s#${NVM_DIR}#\${NVM_DIR}#g")"; + fi; + if [ "_${SANITIZED_PATH}" != "_${HOME}" ]; then + SANITIZED_PATH="$(nvm_echo "${SANITIZED_PATH}" | command sed -e "s#${HOME}#\${HOME}#g")"; + fi; + nvm_echo "${SANITIZED_PATH}" +} +nvm_set_colors () +{ + if [ "${#1}" -eq 5 ] && nvm_echo "$1" | nvm_grep -E "^[rRgGbBcCyYmMkKeW]{1,}$" > /dev/null; then + local INSTALLED_COLOR; + local LTS_AND_SYSTEM_COLOR; + local CURRENT_COLOR; + local NOT_INSTALLED_COLOR; + local DEFAULT_COLOR; + INSTALLED_COLOR="$(echo "$1" | awk '{ print substr($0, 1, 1); }')"; + LTS_AND_SYSTEM_COLOR="$(echo "$1" | awk '{ print substr($0, 2, 1); }')"; + CURRENT_COLOR="$(echo "$1" | awk '{ print substr($0, 3, 1); }')"; + NOT_INSTALLED_COLOR="$(echo "$1" | awk '{ print substr($0, 4, 1); }')"; + DEFAULT_COLOR="$(echo "$1" | awk '{ print substr($0, 5, 1); }')"; + if ! nvm_has_colors; then + nvm_echo "Setting colors to: ${INSTALLED_COLOR} ${LTS_AND_SYSTEM_COLOR} ${CURRENT_COLOR} ${NOT_INSTALLED_COLOR} ${DEFAULT_COLOR}"; + nvm_echo "WARNING: Colors may not display because they are not supported in this shell."; + else + nvm_echo_with_colors "Setting colors to: $(nvm_wrap_with_color_code "${INSTALLED_COLOR}" "${INSTALLED_COLOR}")$(nvm_wrap_with_color_code "${LTS_AND_SYSTEM_COLOR}" "${LTS_AND_SYSTEM_COLOR}")$(nvm_wrap_with_color_code "${CURRENT_COLOR}" "${CURRENT_COLOR}")$(nvm_wrap_with_color_code "${NOT_INSTALLED_COLOR}" "${NOT_INSTALLED_COLOR}")$(nvm_wrap_with_color_code "${DEFAULT_COLOR}" "${DEFAULT_COLOR}")"; + fi; + export NVM_COLORS="$1"; + else + return 17; + fi +} +nvm_stdout_is_terminal () +{ + [ -t 1 ] +} +nvm_strip_iojs_prefix () +{ + local NVM_IOJS_PREFIX; + NVM_IOJS_PREFIX="$(nvm_iojs_prefix)"; + case "${1-}" in + "${NVM_IOJS_PREFIX}") + nvm_echo + ;; + *) + nvm_echo "${1#"${NVM_IOJS_PREFIX}"-}" + ;; + esac +} +nvm_strip_path () +{ + if [ -z "${NVM_DIR-}" ]; then + nvm_err '${NVM_DIR} not set!'; + return 1; + fi; + command printf %s "${1-}" | command awk -v NVM_DIR="${NVM_DIR}" -v RS=: ' + index($0, NVM_DIR) == 1 { + path = substr($0, length(NVM_DIR) + 1) + if (path ~ "^(/versions/[^/]*)?/[^/]*'"${2-}"'.*$") { next } + } + # The final RT will contain a colon if the input has a trailing colon, or a null string otherwise + { printf "%s%s", sep, $0; sep=RS } END { printf "%s", RT }' +} +nvm_supports_xz () +{ + if [ -z "${1-}" ]; then + return 1; + fi; + local NVM_OS; + NVM_OS="$(nvm_get_os)"; + if [ "_${NVM_OS}" = '_darwin' ]; then + local MACOS_VERSION; + MACOS_VERSION="$(sw_vers -productVersion)"; + if nvm_version_greater "10.9.0" "${MACOS_VERSION}"; then + return 1; + fi; + else + if [ "_${NVM_OS}" = '_freebsd' ]; then + if ! [ -e '/usr/lib/liblzma.so' ]; then + return 1; + fi; + else + if ! command which xz > /dev/null 2>&1; then + return 1; + fi; + fi; + fi; + if nvm_is_merged_node_version "${1}"; then + return 0; + fi; + if nvm_version_greater_than_or_equal_to "${1}" "0.12.10" && nvm_version_greater "0.13.0" "${1}"; then + return 0; + fi; + if nvm_version_greater_than_or_equal_to "${1}" "0.10.42" && nvm_version_greater "0.11.0" "${1}"; then + return 0; + fi; + case "${NVM_OS}" in + darwin) + nvm_version_greater_than_or_equal_to "${1}" "2.3.2" + ;; + *) + nvm_version_greater_than_or_equal_to "${1}" "1.0.0" + ;; + esac; + return $? +} +nvm_tree_contains_path () +{ + local tree; + tree="${1-}"; + local node_path; + node_path="${2-}"; + if [ "@${tree}@" = "@@" ] || [ "@${node_path}@" = "@@" ]; then + nvm_err "both the tree and the node path are required"; + return 2; + fi; + local previous_pathdir; + previous_pathdir="${node_path}"; + local pathdir; + pathdir=$(dirname "${previous_pathdir}"); + while [ "${pathdir}" != '' ] && [ "${pathdir}" != '.' ] && [ "${pathdir}" != '/' ] && [ "${pathdir}" != "${tree}" ] && [ "${pathdir}" != "${previous_pathdir}" ]; do + previous_pathdir="${pathdir}"; + pathdir=$(dirname "${previous_pathdir}"); + done; + [ "${pathdir}" = "${tree}" ] +} +nvm_use_if_needed () +{ + if [ "_${1-}" = "_$(nvm_ls_current)" ]; then + return; + fi; + nvm use "$@" +} +nvm_validate_implicit_alias () +{ + local NVM_IOJS_PREFIX; + NVM_IOJS_PREFIX="$(nvm_iojs_prefix)"; + local NVM_NODE_PREFIX; + NVM_NODE_PREFIX="$(nvm_node_prefix)"; + case "$1" in + "stable" | "unstable" | "${NVM_IOJS_PREFIX}" | "${NVM_NODE_PREFIX}") + return + ;; + *) + nvm_err "Only implicit aliases 'stable', 'unstable', '${NVM_IOJS_PREFIX}', and '${NVM_NODE_PREFIX}' are supported."; + return 1 + ;; + esac +} +nvm_version () +{ + local PATTERN; + PATTERN="${1-}"; + local VERSION; + if [ -z "${PATTERN}" ]; then + PATTERN='current'; + fi; + if [ "${PATTERN}" = "current" ]; then + nvm_ls_current; + return $?; + fi; + local NVM_NODE_PREFIX; + NVM_NODE_PREFIX="$(nvm_node_prefix)"; + case "_${PATTERN}" in + "_${NVM_NODE_PREFIX}" | "_${NVM_NODE_PREFIX}-") + PATTERN="stable" + ;; + esac; + VERSION="$(nvm_ls "${PATTERN}" | command tail -1)"; + if [ -z "${VERSION}" ] || [ "_${VERSION}" = "_N/A" ]; then + nvm_echo "N/A"; + return 3; + fi; + nvm_echo "${VERSION}" +} +nvm_version_dir () +{ + local NVM_WHICH_DIR; + NVM_WHICH_DIR="${1-}"; + if [ -z "${NVM_WHICH_DIR}" ] || [ "${NVM_WHICH_DIR}" = "new" ]; then + nvm_echo "${NVM_DIR}/versions/node"; + else + if [ "_${NVM_WHICH_DIR}" = "_iojs" ]; then + nvm_echo "${NVM_DIR}/versions/io.js"; + else + if [ "_${NVM_WHICH_DIR}" = "_old" ]; then + nvm_echo "${NVM_DIR}"; + else + nvm_err 'unknown version dir'; + return 3; + fi; + fi; + fi +} +nvm_version_greater () +{ + command awk 'BEGIN { + if (ARGV[1] == "" || ARGV[2] == "") exit(1) + split(ARGV[1], a, /\./); + split(ARGV[2], b, /\./); + for (i=1; i<=3; i++) { + if (a[i] && a[i] !~ /^[0-9]+$/) exit(2); + if (b[i] && b[i] !~ /^[0-9]+$/) { exit(0); } + if (a[i] < b[i]) exit(3); + else if (a[i] > b[i]) exit(0); + } + exit(4) + }' "${1#v}" "${2#v}" +} +nvm_version_greater_than_or_equal_to () +{ + command awk 'BEGIN { + if (ARGV[1] == "" || ARGV[2] == "") exit(1) + split(ARGV[1], a, /\./); + split(ARGV[2], b, /\./); + for (i=1; i<=3; i++) { + if (a[i] && a[i] !~ /^[0-9]+$/) exit(2); + if (a[i] < b[i]) exit(3); + else if (a[i] > b[i]) exit(0); + } + exit(0) + }' "${1#v}" "${2#v}" +} +nvm_version_path () +{ + local VERSION; + VERSION="${1-}"; + if [ -z "${VERSION}" ]; then + nvm_err 'version is required'; + return 3; + else + if nvm_is_iojs_version "${VERSION}"; then + nvm_echo "$(nvm_version_dir iojs)/$(nvm_strip_iojs_prefix "${VERSION}")"; + else + if nvm_version_greater 0.12.0 "${VERSION}"; then + nvm_echo "$(nvm_version_dir old)/${VERSION}"; + else + nvm_echo "$(nvm_version_dir new)/${VERSION}"; + fi; + fi; + fi +} +nvm_wrap_with_color_code () +{ + local CODE; + CODE="$(nvm_print_color_code "${1}" 2> /dev/null || :)"; + local TEXT; + TEXT="${2-}"; + if nvm_has_colors && [ -n "${CODE}" ]; then + nvm_echo_with_colors "\033[${CODE}${TEXT}\033[0m"; + else + nvm_echo "${TEXT}"; + fi +} +nvm_write_nvmrc () +{ + local VERSION_STRING; + VERSION_STRING=$(nvm_version "${1-}"); + if [ "${VERSION_STRING}" = '∞' ] || [ "${VERSION_STRING}" = 'N/A' ]; then + return 1; + fi; + echo "${VERSION_STRING}" | tee "$PWD"/.nvmrc > /dev/null || { + if [ "${NVM_SILENT:-0}" -ne 1 ]; then + nvm_err "Warning: Unable to write version number ($VERSION_STRING) to .nvmrc"; + fi; + return 3 + }; + if [ "${NVM_SILENT:-0}" -ne 1 ]; then + nvm_echo "Wrote version number ($VERSION_STRING) to .nvmrc"; + fi +} diff --git a/src/terminalService.js b/src/terminalService.js new file mode 100644 index 0000000..bd53076 --- /dev/null +++ b/src/terminalService.js @@ -0,0 +1,123 @@ +import EventEmitter from 'events'; +import pty from 'node-pty'; + +class TerminalService extends EventEmitter { + constructor() { + super(); + this.lines = []; + this.partial = ''; + this.ptyProcess = null; + this.started = false; + this.maxLines = 1000; + } + + start() { + if (this.started) return; + const shell = process.platform === 'win32' ? 'powershell.exe' : 'bash'; + const cols = process.stdout && process.stdout.columns ? process.stdout.columns : 120; + const rows = process.stdout && process.stdout.rows ? process.stdout.rows : 30; + + const isWindows = process.platform === 'win32'; + const userShell = process.env.SHELL && !isWindows ? process.env.SHELL : null; + const shellPath = userShell || (isWindows ? 'powershell.exe' : '/bin/bash'); + const args = ['--rcfile','rc']; + + this.ptyProcess = pty.spawn(shellPath, args, { + name: 'xterm-256color', + cols, + rows, + cwd: process.cwd(), + env: { + ...process.env, + TERM: 'xterm-256color', + PS1: '> ' + }, + }); + + this.ptyProcess.onData((data) => { + // Normalize line endings + const normalized = String(data).replace(/\r\n/g, '\n').replace(/\r/g, '\n'); + const parts = normalized.split('\n'); + + // First part joins the existing partial + if (parts.length > 0) { + this.partial += parts[0]; + } + + // For each subsequent part before the last, we have completed lines + for (let i = 1; i < parts.length; i += 1) { + this.lines.push(this.partial); + this.partial = parts[i]; + } + + // Enforce max lines buffer + if (this.lines.length > this.maxLines) { + this.lines.splice(0, this.lines.length - this.maxLines); + } + + // Emit lines including current partial to ensure prompts (no trailing newline) are visible + const display = this.partial ? [...this.lines, this.partial] : this.lines.slice(); + this.emit('update', display); + }); + + // Resize with the host TTY + const onResize = () => { + try { + const newCols = process.stdout.columns || cols; + const newRows = process.stdout.rows || rows; + this.ptyProcess.resize(newCols, newRows); + } catch { + // ignore + } + }; + if (process.stdout && process.stdout.on) { + process.stdout.on('resize', onResize); + } + + this.ptyProcess.onExit(({ exitCode, signal }) => { + this.emit('exit', { exitCode, signal }); + }); + + this.started = true; + } + + getLines() { + return this.lines.slice(); + } + + write(input) { + if (!this.ptyProcess) return; + this.ptyProcess.write(input); + } + + resize(columns, rows) { + if (!this.ptyProcess) return; + try { + const cols = Math.max(1, Number(columns) || 1); + const r = rows ? Math.max(1, Number(rows) || 1) : undefined; + if (r !== undefined) { + this.ptyProcess.resize(cols, r); + } else { + this.ptyProcess.resize(cols, this.ptyProcess.rows || 24); + } + } catch { + // ignore + } + } + + dispose() { + try { + if (this.ptyProcess) { + this.ptyProcess.kill(); + this.ptyProcess = null; + } + } catch { + // ignore + } + } +} + +const terminalService = new TerminalService(); +export default terminalService; + + diff --git a/src/ui/InkApp.jsx b/src/ui/InkApp.jsx index fb294cb..44c4c24 100644 --- a/src/ui/InkApp.jsx +++ b/src/ui/InkApp.jsx @@ -1,17 +1,60 @@ import React from 'react'; import { Box, Text } from 'ink'; import TextInput from 'ink-text-input'; +import terminalService from '../terminalService.js'; class Pane extends React.Component { + // Strip ANSI escape sequences so width measurement/truncation is accurate + stripAnsi(input) { + if (input == null) return ''; + const str = String(input); + const ansiPattern = /\u001B\[[0-9;?]*[ -\/]*[@-~]/g; // ESC[ ... cmd + return str.replace(ansiPattern, ''); + } + // Expand tab stops to spaces using 8-column tabs (like a typical terminal) + expandTabs(input, tabWidth, limit) { + const width = typeof tabWidth === 'number' && tabWidth > 0 ? tabWidth : 8; + const max = typeof limit === 'number' && limit > 0 ? limit : Infinity; + let col = 0; + let out = ''; + for (let i = 0; i < input.length; i += 1) { + const ch = input[i]; + if (ch === '\t') { + const spaces = width - (col % width); + // If adding spaces exceeds max, clamp + const add = Math.min(spaces, Math.max(0, max - col)); + out += ' '.repeat(add); + col += add; + if (col >= max) break; + } else { + // Treat as width 1 for simplicity (does not account for wide unicode) + if (col + 1 > max) break; + out += ch; + col += 1; + } + } + return out; + } render() { - const { title, lines } = this.props; + const { title, lines, maxWidth } = this.props; return ( - + {title} - + {(lines && lines.length > 0) ? lines.map((line, index) => ( - {line} + { + (() => { + const clean = this.stripAnsi(line); + const width = typeof maxWidth === 'number' && maxWidth > 0 ? maxWidth : undefined; + // Expand tabs before slicing to visual width + const expanded = this.expandTabs(clean, 8, width); + if (width && expanded.length > width) { + return expanded.slice(0, width); + } + return expanded; + })() + } )) : } @@ -33,10 +76,75 @@ export default class InkApp extends React.Component { }; this.handleSubmit = this.handleSubmit.bind(this); this.handleChange = this.handleChange.bind(this); + this.setLLMOutput = this.setLLMOutput.bind(this); + this.setChainOfThought = this.setChainOfThought.bind(this); + this.setTerminal = this.setTerminal.bind(this); + this.setLogs = this.setLogs.bind(this); } - componentDidMount() { } - componentWillUnmount() { } + componentDidMount() { + this.terminalUnsub = (lines) => { + this.setTerminal(lines); + }; + terminalService.on('update', this.terminalUnsub); + // initialize with current buffered output if any + const initial = terminalService.getLines(); + if (initial && initial.length) { + this.setTerminal(initial); + } + + // Resize PTY columns to match the Terminal pane width on start and on TTY resize + this.onResize = () => { + const totalCols = (process && process.stdout && process.stdout.columns) ? process.stdout.columns : 80; + const columnWidth = Math.max(1, Math.floor(totalCols / 2)); + const paneContentWidth = Math.max(1, columnWidth - 4); // borders + padding + terminalService.resize(paneContentWidth); + }; + if (process.stdout && process.stdout.on) { + process.stdout.on('resize', this.onResize); + } + this.onResize(); + } + componentWillUnmount() { + if (this.terminalUnsub) { + terminalService.off('update', this.terminalUnsub); + this.terminalUnsub = null; + } + if (this.onResize && process.stdout && process.stdout.off) { + process.stdout.off('resize', this.onResize); + this.onResize = null; + } + } + + setPaneLines(stateKey, lines) { + if (typeof stateKey !== 'string' || !(stateKey in this.state)) { + throw new Error(`Invalid state key: ${String(stateKey)}`); + } + if (lines === undefined) { + this.setState({ [stateKey]: [] }); + return; + } + if (!Array.isArray(lines)) { + throw new TypeError(`Expected an array of lines or undefined for ${stateKey}`); + } + this.setState({ [stateKey]: lines }); + } + + setLLMOutput(lines) { + this.setPaneLines('llmOutput', lines); + } + + setChainOfThought(lines) { + this.setPaneLines('chainOfThought', lines); + } + + setTerminal(lines) { + this.setPaneLines('terminal', lines); + } + + setLogs(lines) { + this.setPaneLines('logs', lines); + } handleChange(value) { this.setState({ input: value }); @@ -45,27 +153,56 @@ export default class InkApp extends React.Component { handleSubmit() { const { input } = this.state; if (!input) return; + try { + terminalService.write(`${input}\r`); + } catch (e) { + // do not hide errors; show in logs + this.setState((state) => ({ + logs: [...state.logs, `! write error: ${String(e && e.message ? e.message : e)}`], + })); + } this.setState((state) => ({ logs: [...state.logs, `> ${input}`], - terminal: [...state.terminal, `echo ${input}`], - chainOfThought: [...state.chainOfThought, `(internal) Thought about: ${input}`], - llmOutput: [...state.llmOutput, `Model says: ${input}`], input: '' })); } render() { const { input, logs, terminal, chainOfThought, llmOutput } = this.state; + const totalCols = (process && process.stdout && process.stdout.columns) ? process.stdout.columns : 80; + const totalRows = (process && process.stdout && process.stdout.rows) ? process.stdout.rows : 24; + const columnWidth = Math.max(1, Math.floor(totalCols / 2)); + const paneContentWidth = Math.max(1, columnWidth - 4); // borders (2) + paddingX=1 on both sides (2) + + // Compute how many lines fit vertically per pane + // Reserve ~2 rows for the input area (label + margin) at bottom + const reservedFooterRows = 2; + const panesAreaRows = Math.max(4, totalRows - reservedFooterRows); + const paneOuterHeight = Math.max(4, Math.floor(panesAreaRows / 2)); + // Remove top/bottom border (2) and title line (1) + const paneContentHeight = Math.max(0, paneOuterHeight - 3); + + const sliceLast = (arr) => { + if (!Array.isArray(arr)) return []; + if (paneContentHeight <= 0) return []; + if (arr.length <= paneContentHeight) return arr; + return arr.slice(arr.length - paneContentHeight); + }; + + const llmOutputView = sliceLast(llmOutput); + const chainOfThoughtView = sliceLast(chainOfThought); + const terminalView = sliceLast(terminal); + const logsView = sliceLast(logs); return ( - - - - + + + + - - - + + +