From 52efeb10581185af7a495de3d67ae05d1598fe70 Mon Sep 17 00:00:00 2001 From: Corey Butler <770982+coreybutler@users.noreply.github.com> Date: Tue, 27 Oct 2026 10:23:46 -0500 Subject: [PATCH] fix(resolver): skip index.tab for exact versions Air-gapped nvm install of a concrete x.y.z fetched nodejs.org/dist/index.tab before using a local archive. Signed-off-by: Corey Butler <770982+coreybutler@users.noreply.github.com> --- resolver/resolver.go | 9 ++++----- resolver/resolver_test.go | 18 ++++++++++++++++++ 2 files changed, 22 insertions(+), 5 deletions(-) create mode 100644 resolver/resolver_test.go diff --git a/resolver/resolver.go b/resolver/resolver.go index 04dcaef..fe6cc6e 100644 --- a/resolver/resolver.go +++ b/resolver/resolver.go @@ -26,14 +26,12 @@ func Find(version string) (string, string, error) { isUserAlias = true } - resolvedViaAlias := false if isUserAlias || lower == "latest" || lower == "lts" || strings.HasPrefix(lower, "lts/") { resolved, err := alias(lower) if err != nil { return "", "", err } v = resolved - resolvedViaAlias = true } // Strip prerelease/build metadata for matching purposes. @@ -41,9 +39,10 @@ func Find(version string) (string, string, error) { // implemented with Alpha releases. v = strings.Split(v, "-")[0] - // After alias resolution the target may already be exact (user alias, - // default/current, or latest/lts). Skip a second index.tab fetch. - if resolvedViaAlias && isExactVersionSpec(v) { + // Exact x.y.z is already concrete (typed by the user, or after alias + // resolution). Skip index.tab so air-gapped `nvm install 24.22.1` can + // use a local archive without DNS. + if isExactVersionSpec(v) { return NormalizeVersion(v), "", nil } diff --git a/resolver/resolver_test.go b/resolver/resolver_test.go new file mode 100644 index 0000000..e751b9f --- /dev/null +++ b/resolver/resolver_test.go @@ -0,0 +1,18 @@ +package resolver + +import "testing" + +func TestFindExactVersionSkipsCatalog(t *testing.T) { + for _, spec := range []string{"24.22.1", "v24.22.1", "24.22.1-rc.1"} { + got, npm, err := Find(spec) + if err != nil { + t.Fatalf("Find(%q) error = %v", spec, err) + } + if got != "24.22.1" { + t.Fatalf("Find(%q) = %q, want 24.22.1", spec, got) + } + if npm != "" { + t.Fatalf("Find(%q) npm = %q, want empty (no catalog)", spec, npm) + } + } +}