Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion packages/cli-kit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,6 @@
"is-executable": "2.0.2",
"is-wsl": "3.1.1",
"jose": "5.10.0",
"latest-version": "7.0.0",
"liquidjs": "10.27.0",
"lodash": "4.18.1",
"macaddress": "0.5.4",
Expand Down
31 changes: 18 additions & 13 deletions packages/cli-kit/src/public/node/node-package-manager.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,21 @@ import {captureOutput, exec} from './system.js'
import {inTemporaryDirectory, mkdir, touchFile, writeFile} from './fs.js'
import {joinPath, dirname, normalizePath} from './path.js'
import {inferPackageManagerForGlobalCLI} from './is-global.js'
import {fetch} from './http.js'
import {cacheClear} from '../../private/node/conf-store.js'
import latestVersion from 'latest-version'
import {vi, describe, test, expect, beforeEach, afterEach} from 'vitest'

vi.mock('./version.js')
vi.mock('./system.js')
vi.mock('latest-version')
vi.mock('./http.js')
vi.mock('./is-global')

const mockedExec = vi.mocked(exec)

function mockNpmRegistryLatestVersion(version: string) {
const response = {ok: true, statusText: 'OK', json: () => Promise.resolve({version})}
vi.mocked(fetch).mockResolvedValue(response as unknown as Awaited<ReturnType<typeof fetch>>)
}
const mockedCaptureOutput = vi.mocked(captureOutput)

describe('installNPMDependenciesRecursively', () => {
Expand Down Expand Up @@ -558,7 +563,7 @@ describe('checkForCachedNewVersion', () => {
const currentVersion = '2.2.2'
const newestVersion = '2.2.2'
const dependency = 'dependency'
vi.mocked(latestVersion).mockResolvedValue(newestVersion)
mockNpmRegistryLatestVersion(newestVersion)
await checkForNewVersion(dependency, currentVersion)

// When
Expand All @@ -573,7 +578,7 @@ describe('checkForCachedNewVersion', () => {
const currentVersion = '2.2.2'
const newestVersion = '2.2.3'
const dependency = 'dependency'
vi.mocked(latestVersion).mockResolvedValue(newestVersion)
mockNpmRegistryLatestVersion(newestVersion)
await checkForNewVersion(dependency, currentVersion)

// When
Expand All @@ -595,7 +600,7 @@ describe('checkForNewVersion', () => {
const currentVersion = '2.2.2'
const newestVersion = '2.2.2'
const dependency = 'dependency'
vi.mocked(latestVersion).mockResolvedValue(newestVersion)
mockNpmRegistryLatestVersion(newestVersion)

// When
const result = await checkForNewVersion(dependency, currentVersion)
Expand All @@ -609,7 +614,7 @@ describe('checkForNewVersion', () => {
const currentVersion = '2.2.2'
const newestVersion = '2.2.3'
const dependency = 'dependency'
vi.mocked(latestVersion).mockResolvedValue(newestVersion)
mockNpmRegistryLatestVersion(newestVersion)

// When
const result = await checkForNewVersion(dependency, currentVersion)
Expand All @@ -622,7 +627,7 @@ describe('checkForNewVersion', () => {
// Given
const currentVersion = '2.2.2'
const dependency = 'dependency'
vi.mocked(latestVersion).mockRejectedValue(undefined)
vi.mocked(fetch).mockRejectedValue(undefined)

// When
const result = await checkForNewVersion(dependency, currentVersion)
Expand All @@ -636,7 +641,7 @@ describe('checkForNewVersion', () => {
const currentVersion = '2.2.2'
const newestVersion = '2.2.3'
const dependency = 'dependency'
vi.mocked(latestVersion).mockResolvedValue(newestVersion)
mockNpmRegistryLatestVersion(newestVersion)

// When
await checkForNewVersion(dependency, currentVersion)
Expand All @@ -645,15 +650,15 @@ describe('checkForNewVersion', () => {

// Then
expect(result).toBe(newestVersion)
expect(latestVersion).toHaveBeenCalledTimes(1)
expect(fetch).toHaveBeenCalledTimes(1)
})

test('refreshes results when given a nonzero timeout that has expired', async () => {
// Given
const currentVersion = '2.2.2'
const newestVersion = '2.2.3'
const dependency = 'dependency'
vi.mocked(latestVersion).mockResolvedValue(newestVersion)
mockNpmRegistryLatestVersion(newestVersion)

// When
await checkForNewVersion(dependency, currentVersion)
Expand All @@ -662,23 +667,23 @@ describe('checkForNewVersion', () => {

// Then
expect(result).toBe(newestVersion)
expect(latestVersion).toHaveBeenCalledTimes(2)
expect(fetch).toHaveBeenCalledTimes(2)
})

test('refreshes results when given no timeout', async () => {
// Given
const currentVersion = '2.2.2'
const newestVersion = '2.2.3'
const dependency = 'dependency'
vi.mocked(latestVersion).mockResolvedValue(newestVersion)
mockNpmRegistryLatestVersion(newestVersion)

// When
await checkForNewVersion(dependency, currentVersion)
const result = await checkForNewVersion(dependency, currentVersion)

// Then
expect(result).toBe(newestVersion)
expect(latestVersion).toHaveBeenCalledTimes(2)
expect(fetch).toHaveBeenCalledTimes(2)
})
})

Expand Down
9 changes: 7 additions & 2 deletions packages/cli-kit/src/public/node/node-package-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {dirname, joinPath} from './path.js'
import {runWithTimer} from './metadata.js'
import {inferPackageManagerForGlobalCLI} from './is-global.js'
import {outputToken, outputContent, outputDebug} from './output.js'
import {fetch} from './http.js'
import {PackageVersionKey, cacheRetrieve, cacheRetrieveOrRepopulate} from '../../private/node/conf-store.js'
import {parseJSON} from '../common/json.js'
import {SemVer, satisfies as semverSatisfies} from 'semver'
Expand Down Expand Up @@ -702,8 +703,12 @@ export async function addResolutionOrOverride(directory: string, dependencies: R
async function getLatestNPMPackageVersion(name: string) {
outputDebug(outputContent`Getting the latest version of NPM package: ${outputToken.raw(name)}`)
return runWithTimer('cmd_all_timing_network_ms')(async () => {
const {default: latestVersion} = await import('latest-version')
return latestVersion(name)
const response = await fetch(`https://registry.npmjs.org/${name}/latest`)
if (!response.ok) {
throw new AbortError(`Failed to get the latest version of ${name}: ${response.statusText}`)
}
const packageManifest = (await response.json()) as {version: string}
return packageManifest.version
})
}

Expand Down
Loading
Loading