diff --git a/packages/core/src/plugins/publish.ts b/packages/core/src/plugins/publish.ts index b93b771..c001d5f 100644 --- a/packages/core/src/plugins/publish.ts +++ b/packages/core/src/plugins/publish.ts @@ -2,7 +2,7 @@ import { Context, cwd, exit, Manager, PackageJson, spawnAsync } from '../index.j import { gt, prerelease } from 'semver' import { Awaitable } from 'cosmokit' import { join } from 'path' -import { latest } from '../utils.js' +import { fetchRemote, selectVersion } from '../utils.js' import ora from 'ora' import prompts from 'prompts' import assert from 'assert' @@ -18,11 +18,13 @@ declare module '../index.js' { } } -function getVersion(name: string, isNext = false) { +async function getVersion(name: string, isNext = false) { + const remote = await fetchRemote(name).catch(() => null) + if (!remote) return '0.0.0' if (isNext) { - return latest(name, { version: 'next' }).catch(() => getVersion(name)) + return selectVersion(remote, 'next') || selectVersion(remote, 'latest') || '0.0.0' } else { - return latest(name, { version: 'latest' }).catch(() => '0.0.1') + return selectVersion(remote, 'latest') || '0.0.0' } } diff --git a/packages/core/src/plugins/upgrade.ts b/packages/core/src/plugins/upgrade.ts index 23440ad..03b7ab7 100644 --- a/packages/core/src/plugins/upgrade.ts +++ b/packages/core/src/plugins/upgrade.ts @@ -1,7 +1,7 @@ import { Context, DependencyType, PackageJson, spawnAsync } from '../index.js' import kleur from 'kleur' import { gt } from 'semver' -import { latest } from '../utils.js' +import { fetchRemote, selectVersion } from '../utils.js' import pMap from 'p-map' import ora from 'ora' @@ -41,11 +41,13 @@ export function apply(ctx: Context, config: Config = {}) { const [dep, oldRange] = request.split(':') if (names.includes(dep)) return updateProgress() const oldVersion = oldRange.slice(1) - const [newVersion, lastestVersion] = await Promise.all([ - latest(dep, { version: oldRange }), - latest(dep, { version: ctx.yakumo.argv.next ? '' : 'latest' }), - ]) + const remote = await fetchRemote(dep).catch(() => { + console.log(`- ${kleur.red(dep)}: failed to fetch`) + }) updateProgress() + if (!remote) return + const newVersion = selectVersion(remote, oldRange) + const lastestVersion = selectVersion(remote, ctx.yakumo.argv.next ? '' : 'latest') try { if (!gt(newVersion, oldVersion)) return } catch (error) { @@ -53,7 +55,8 @@ export function apply(ctx: Context, config: Config = {}) { return } const newRange = oldRange[0] + newVersion - output.push(`- ${kleur.yellow(dep)}: ${kleur.cyan(oldVersion)} -> ${kleur.green(newVersion)}${newVersion === lastestVersion ? '' : ` (latest: ${lastestVersion})`}`) + const suffix = newVersion === lastestVersion ? '' : ` (latest: ${lastestVersion})` + output.push(`- ${kleur.yellow(dep)}: ${kleur.cyan(oldVersion)} -> ${kleur.green(newVersion)}${suffix}`) for (const name in deps[request]) { Object.defineProperty(ctx.yakumo.workspaces[name], '$dirty', { value: true }) for (const type in deps[request][name]) { diff --git a/packages/core/src/utils.ts b/packages/core/src/utils.ts index 32f1153..f04b650 100644 --- a/packages/core/src/utils.ts +++ b/packages/core/src/utils.ts @@ -39,13 +39,7 @@ export async function install() { let registryTask: Promise -export namespace latest { - export interface Options { - version: string - } -} - -export async function latest(name: string, options: latest.Options) { +export async function fetchRemote(name: string) { const registry = await (registryTask ||= getRegistry()) const packageUrl = new URL(encodeURIComponent(name).replace(/^%40/, '@'), registry) const response = await fetch(packageUrl, { @@ -53,14 +47,17 @@ export async function latest(name: string, options: latest.Options) { 'Accept': 'application/vnd.npm.install-v1+json; q=1.0, application/json; q=0.8, */*', }, }) - const { version } = options - const data = await response.json() + if (!response.ok) throw new Error(`Failed to fetch ${packageUrl}`) + return response.json() +} + +export function selectVersion(data: any, version: string) { if (data['dist-tags'][version]) { return data['dist-tags'][version] - } else if (data.versions[version]) { + } else if (data.versions?.[version]) { return version } else { const versions = Object.keys(data.versions) - return semver.maxSatisfying(versions, version, { includePrerelease: true }) + return semver.maxSatisfying(versions, version, { includePrerelease: true, loose: true }) } }