refactor: rename pref to bare specifier (#9445)

This commit is contained in:
Zoltan Kochan
2025-04-20 22:58:08 +02:00
committed by GitHub
parent 56bb69b004
commit 8a9f3a4835
87 changed files with 660 additions and 638 deletions

View File

@@ -0,0 +1,22 @@
---
"@pnpm/plugin-commands-installation": major
"@pnpm/parse-wanted-dependency": major
"@pnpm/resolve-dependencies": major
"@pnpm/package-requester": major
"@pnpm/store-controller-types": major
"@pnpm/render-peer-issues": major
"@pnpm/default-resolver": major
"@pnpm/tarball-resolver": major
"@pnpm/catalogs.protocol-parser": major
"@pnpm/local-resolver": major
"@pnpm/resolver-base": major
"@pnpm/parse-overrides": major
"@pnpm/git-resolver": major
"@pnpm/npm-resolver": major
"@pnpm/core-loggers": major
"@pnpm/core": major
"@pnpm/logger": major
"@pnpm/config": major
---
`pref` renamed to `bareSpecifier`.

View File

@@ -4,12 +4,12 @@ const CATALOG_PROTOCOL = 'catalog:'
* Parse a package.json dependency specifier using the catalog: protocol.
* Returns null if the given specifier does not start with 'catalog:'.
*/
export function parseCatalogProtocol (pref: string): string | 'default' | null {
if (!pref.startsWith(CATALOG_PROTOCOL)) {
export function parseCatalogProtocol (bareSpecifier: string): string | 'default' | null {
if (!bareSpecifier.startsWith(CATALOG_PROTOCOL)) {
return null
}
const catalogNameRaw = pref.slice(CATALOG_PROTOCOL.length).trim()
const catalogNameRaw = bareSpecifier.slice(CATALOG_PROTOCOL.length).trim()
// Allow a specifier of 'catalog:' to be a short-hand for 'catalog:default'.
const catalogNameNormalized = catalogNameRaw === '' ? 'default' : catalogNameRaw

View File

@@ -3,7 +3,7 @@ import { parseCatalogProtocol } from '@pnpm/catalogs.protocol-parser'
import { type Catalogs } from '@pnpm/catalogs.types'
export interface WantedDependency {
readonly pref: string
readonly bareSpecifier: string
readonly alias: string
}
@@ -58,7 +58,7 @@ export interface CatalogResolutionUnused {
}
export function resolveFromCatalog (catalogs: Catalogs, wantedDependency: WantedDependency): CatalogResolutionResult {
const catalogName = parseCatalogProtocol(wantedDependency.pref)
const catalogName = parseCatalogProtocol(wantedDependency.bareSpecifier)
if (catalogName == null) {
return { type: 'unused' }

View File

@@ -10,12 +10,12 @@ describe('default catalog', () => {
}
test('resolves using implicit name', () => {
expect(resolveFromCatalog(catalogs, { alias: 'foo', pref: 'catalog:' }))
expect(resolveFromCatalog(catalogs, { alias: 'foo', bareSpecifier: 'catalog:' }))
.toEqual({ type: 'found', resolution: { catalogName: 'default', specifier: '1.0.0' } })
})
test('resolves using explicit name', () => {
expect(resolveFromCatalog(catalogs, { alias: 'foo', pref: 'catalog:default' }))
expect(resolveFromCatalog(catalogs, { alias: 'foo', bareSpecifier: 'catalog:default' }))
.toEqual({ type: 'found', resolution: { catalogName: 'default', specifier: '1.0.0' } })
})
})
@@ -27,7 +27,7 @@ test('resolves named catalog', () => {
},
}
expect(resolveFromCatalog(catalogs, { alias: 'bar', pref: 'catalog:foo' }))
expect(resolveFromCatalog(catalogs, { alias: 'bar', bareSpecifier: 'catalog:foo' }))
.toEqual({ type: 'found', resolution: { catalogName: 'foo', specifier: '1.0.0' } })
})
@@ -38,7 +38,7 @@ test('returns unused for specifier not using catalog protocol', () => {
},
}
expect(resolveFromCatalog(catalogs, { alias: 'bar', pref: '^2.0.0' })).toEqual({ type: 'unused' })
expect(resolveFromCatalog(catalogs, { alias: 'bar', bareSpecifier: '^2.0.0' })).toEqual({ type: 'unused' })
})
describe('misconfiguration', () => {
@@ -57,11 +57,11 @@ describe('misconfiguration', () => {
},
}
expect(() => resolveFromCatalogOrThrow(catalogs, { alias: 'bar', pref: 'catalog:' }))
expect(() => resolveFromCatalogOrThrow(catalogs, { alias: 'bar', bareSpecifier: 'catalog:' }))
.toThrow("No catalog entry 'bar' was found for catalog 'default'.")
expect(() => resolveFromCatalogOrThrow(catalogs, { alias: 'bar', pref: 'catalog:baz' }))
expect(() => resolveFromCatalogOrThrow(catalogs, { alias: 'bar', bareSpecifier: 'catalog:baz' }))
.toThrow("No catalog entry 'bar' was found for catalog 'baz'.")
expect(() => resolveFromCatalogOrThrow(catalogs, { alias: 'foo', pref: 'catalog:foo' }))
expect(() => resolveFromCatalogOrThrow(catalogs, { alias: 'foo', bareSpecifier: 'catalog:foo' }))
.toThrow("No catalog entry 'foo' was found for catalog 'foo'.")
})
@@ -72,7 +72,7 @@ describe('misconfiguration', () => {
},
}
expect(() => resolveFromCatalogOrThrow(catalogs, { alias: 'bar', pref: 'catalog:foo' }))
expect(() => resolveFromCatalogOrThrow(catalogs, { alias: 'bar', bareSpecifier: 'catalog:foo' }))
.toThrow("Found invalid catalog entry using the catalog protocol recursively. The entry for 'bar' in catalog 'foo' is invalid.")
})
@@ -83,7 +83,7 @@ describe('misconfiguration', () => {
},
}
expect(() => resolveFromCatalogOrThrow(catalogs, { alias: 'bar', pref: 'catalog:foo' }))
expect(() => resolveFromCatalogOrThrow(catalogs, { alias: 'bar', bareSpecifier: 'catalog:foo' }))
.toThrow("The workspace protocol cannot be used as a catalog value. The entry for 'bar' in catalog 'foo' is invalid.")
})
@@ -94,7 +94,7 @@ describe('misconfiguration', () => {
},
}
expect(() => resolveFromCatalogOrThrow(catalogs, { alias: 'bar', pref: 'catalog:foo' }))
expect(() => resolveFromCatalogOrThrow(catalogs, { alias: 'bar', bareSpecifier: 'catalog:foo' }))
.toThrow("The entry for 'bar' in catalog 'foo' declares a dependency using the 'file' protocol. This is not yet supported, but may be in a future version of pnpm.")
})
@@ -105,7 +105,7 @@ describe('misconfiguration', () => {
},
}
expect(() => resolveFromCatalogOrThrow(catalogs, { alias: 'bar', pref: 'catalog:foo' }))
expect(() => resolveFromCatalogOrThrow(catalogs, { alias: 'bar', bareSpecifier: 'catalog:foo' }))
.toThrow("The entry for 'bar' in catalog 'foo' declares a dependency using the 'link' protocol. This is not yet supported, but may be in a future version of pnpm.")
})
})

View File

@@ -470,12 +470,12 @@ function reportSpecNotSupportedByAnyResolverError (err: Error, logObj: Log): Err
// protocol is meant to be replaced before it's passed to any of the real
// resolvers.
//
// If this kind of error is thrown, and the dependency pref is using the
// If this kind of error is thrown, and the dependency bareSpecifier is using the
// catalog protocol it's most likely because we're trying to install an out of
// repo dependency that was published incorrectly. For example, it may be been
// mistakenly published with 'npm publish' instead of 'pnpm publish'. Report a
// more clear error in this case.
if (logObj.package?.pref?.startsWith('catalog:')) {
if (logObj.package?.bareSpecifier?.startsWith('catalog:')) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return reportExternalCatalogProtocolError(err, logObj as any)
}

View File

@@ -13,7 +13,7 @@ export function reportSkippedOptionalDependencies (
map((log) => Rx.of({
msg: `info: ${
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
log.package.id || log.package.name && (`${log.package.name}@${log.package.version}`) || log.package.pref
log.package.id || log.package.name && (`${log.package.name}@${log.package.version}`) || log.package.bareSpecifier
} is an optional dependency and failed compatibility check. Excluding it from installation.`,
}))
)

View File

@@ -92,7 +92,7 @@ export interface Config extends OptionsFromRootManifest {
sideEffectsCacheWrite?: boolean
shamefullyHoist?: boolean
dev?: boolean
ignoreCurrentPrefs?: boolean
ignoreCurrentSpecifiers?: boolean
recursive?: boolean
enablePrePostScripts?: boolean
useNodeVersion?: string

View File

@@ -294,7 +294,7 @@ export async function getConfig (opts: {
}
pnpmConfig.save = true
pnpmConfig.allowNew = true
pnpmConfig.ignoreCurrentPrefs = true
pnpmConfig.ignoreCurrentSpecifiers = true
pnpmConfig.saveProd = true
pnpmConfig.saveDev = false
pnpmConfig.saveOptional = false

View File

@@ -9,12 +9,12 @@ export interface VersionOverride {
selector: string
parentPkg?: PackageSelector
targetPkg: PackageSelector
newPref: string
newBareSpecifier: string
}
export interface PackageSelector {
name: string
pref?: string
bareSpecifier?: string
}
export function parseOverrides (
@@ -23,10 +23,10 @@ export function parseOverrides (
): VersionOverride[] {
const _resolveFromCatalog = resolveFromCatalog.bind(null, catalogs ?? {})
return Object.entries(overrides)
.map(([selector, newPref]) => {
.map(([selector, newBareSpecifier]) => {
const result = parsePkgAndParentSelector(selector)
const resolvedCatalog = matchCatalogResolveResult(_resolveFromCatalog({
pref: newPref,
bareSpecifier: newBareSpecifier,
alias: result.targetPkg.name,
}), {
found: ({ resolution }) => resolution.specifier,
@@ -37,7 +37,7 @@ export function parseOverrides (
})
return {
selector,
newPref: resolvedCatalog ?? newPref,
newBareSpecifier: resolvedCatalog ?? newBareSpecifier,
...result,
}
})
@@ -66,6 +66,6 @@ function parsePkgSelector (selector: string): PackageSelector {
}
return {
name: wantedDep.alias,
pref: wantedDep.pref,
bareSpecifier: wantedDep.bareSpecifier,
}
}

View File

@@ -3,11 +3,11 @@ import { parseOverrides } from '@pnpm/parse-overrides'
test.each([
[
{ foo: '1' },
[{ selector: 'foo', newPref: '1', targetPkg: { name: 'foo' } }],
[{ selector: 'foo', newBareSpecifier: '1', targetPkg: { name: 'foo' } }],
],
[
{ 'foo@2': '1' },
[{ selector: 'foo@2', newPref: '1', targetPkg: { name: 'foo', pref: '2' } }],
[{ selector: 'foo@2', newBareSpecifier: '1', targetPkg: { name: 'foo', bareSpecifier: '2' } }],
],
[
{
@@ -15,8 +15,8 @@ test.each([
'foo@3 || >=2': '1',
},
[
{ selector: 'foo@>2', newPref: '1', targetPkg: { name: 'foo', pref: '>2' } },
{ selector: 'foo@3 || >=2', newPref: '1', targetPkg: { name: 'foo', pref: '3 || >=2' } },
{ selector: 'foo@>2', newBareSpecifier: '1', targetPkg: { name: 'foo', bareSpecifier: '>2' } },
{ selector: 'foo@3 || >=2', newBareSpecifier: '1', targetPkg: { name: 'foo', bareSpecifier: '3 || >=2' } },
],
],
[
@@ -27,10 +27,10 @@ test.each([
'bar@1>foo@1': '2',
},
[
{ selector: 'bar>foo', newPref: '2', parentPkg: { name: 'bar' }, targetPkg: { name: 'foo' } },
{ selector: 'bar@1>foo', newPref: '2', parentPkg: { name: 'bar', pref: '1' }, targetPkg: { name: 'foo' } },
{ selector: 'bar>foo@1', newPref: '2', parentPkg: { name: 'bar' }, targetPkg: { name: 'foo', pref: '1' } },
{ selector: 'bar@1>foo@1', newPref: '2', parentPkg: { name: 'bar', pref: '1' }, targetPkg: { name: 'foo', pref: '1' } },
{ selector: 'bar>foo', newBareSpecifier: '2', parentPkg: { name: 'bar' }, targetPkg: { name: 'foo' } },
{ selector: 'bar@1>foo', newBareSpecifier: '2', parentPkg: { name: 'bar', bareSpecifier: '1' }, targetPkg: { name: 'foo' } },
{ selector: 'bar>foo@1', newBareSpecifier: '2', parentPkg: { name: 'bar' }, targetPkg: { name: 'foo', bareSpecifier: '1' } },
{ selector: 'bar@1>foo@1', newBareSpecifier: '2', parentPkg: { name: 'bar', bareSpecifier: '1' }, targetPkg: { name: 'foo', bareSpecifier: '1' } },
],
],
[
@@ -39,8 +39,8 @@ test.each([
'foo@3 || >=2>bar@3 || >=2': '1',
},
[
{ selector: 'foo@>2>bar@>2', newPref: '1', parentPkg: { name: 'foo', pref: '>2' }, targetPkg: { name: 'bar', pref: '>2' } },
{ selector: 'foo@3 || >=2>bar@3 || >=2', newPref: '1', parentPkg: { name: 'foo', pref: '3 || >=2' }, targetPkg: { name: 'bar', pref: '3 || >=2' } },
{ selector: 'foo@>2>bar@>2', newBareSpecifier: '1', parentPkg: { name: 'foo', bareSpecifier: '>2' }, targetPkg: { name: 'bar', bareSpecifier: '>2' } },
{ selector: 'foo@3 || >=2>bar@3 || >=2', newBareSpecifier: '1', parentPkg: { name: 'foo', bareSpecifier: '3 || >=2' }, targetPkg: { name: 'bar', bareSpecifier: '3 || >=2' } },
],
],
])('parseOverrides()', (overrides, expectedResult) => {

View File

@@ -1,15 +1,15 @@
import { type Registries } from '@pnpm/types'
export function pickRegistryForPackage (registries: Registries, packageName: string, pref?: string): string {
const scope = getScope(packageName, pref)
export function pickRegistryForPackage (registries: Registries, packageName: string, bareSpecifier?: string): string {
const scope = getScope(packageName, bareSpecifier)
return (scope && registries[scope]) ?? registries.default
}
function getScope (pkgName: string, pref?: string): string | null {
if (pref?.startsWith('npm:')) {
pref = pref.slice(4)
if (pref[0] === '@') {
return pref.substring(0, pref.indexOf('/'))
function getScope (pkgName: string, bareSpecifier?: string): string | null {
if (bareSpecifier?.startsWith('npm:')) {
bareSpecifier = bareSpecifier.slice(4)
if (bareSpecifier[0] === '@') {
return bareSpecifier.substring(0, bareSpecifier.indexOf('/'))
}
}
if (pkgName[0] === '@') {

View File

@@ -87,10 +87,10 @@ export async function handler (
})
const resolvedPkgAliases: string[] = []
const resolvedPkgs = await Promise.all(pkgs.map(async (pkg) => {
const { alias, pref } = parseWantedDependency(pkg) || {}
const { alias, bareSpecifier } = parseWantedDependency(pkg) || {}
if (alias == null) return pkg
resolvedPkgAliases.push(alias)
const resolved = await resolve({ alias, pref }, {
const resolved = await resolve({ alias, bareSpecifier }, {
lockfileDir: opts.lockfileDir ?? opts.dir,
preferredVersions: {},
projectDir: opts.dir,

View File

@@ -15,11 +15,11 @@ export function createPackageExtender (
const extensionsByPkgName: ExtensionsByPkgName = new Map()
for (const selector in packageExtensions) {
const packageExtension = packageExtensions[selector]
const { alias, pref } = parseWantedDependency(selector)
const { alias, bareSpecifier } = parseWantedDependency(selector)
if (!extensionsByPkgName.has(alias!)) {
extensionsByPkgName.set(alias!, [])
}
extensionsByPkgName.get(alias!)!.push({ packageExtension, range: pref })
extensionsByPkgName.get(alias!)!.push({ packageExtension, range: bareSpecifier })
}
return extendPkgHook.bind(null, extensionsByPkgName) as ReadPackageHook
}

View File

@@ -23,7 +23,7 @@ export function createVersionsOverrider (
const versionOverridesWithParent = versionOverrides.filter(({ parentPkg }) => {
return (
parentPkg.name === manifest.name &&
(!parentPkg.pref || semver.satisfies(manifest.version, parentPkg.pref))
(!parentPkg.bareSpecifier || semver.satisfies(manifest.version, parentPkg.bareSpecifier))
)
})
overrideDepsOfPkg({ manifest, dir }, versionOverridesWithParent, genericVersionOverrides)
@@ -42,14 +42,14 @@ type LocalProtocol = 'link:' | 'file:'
function createLocalTarget (override: VersionOverrideWithoutRawSelector, rootDir: string): LocalTarget | undefined {
let protocol: LocalProtocol | undefined
if (override.newPref.startsWith('file:')) {
if (override.newBareSpecifier.startsWith('file:')) {
protocol = 'file:'
} else if (override.newPref.startsWith('link:')) {
} else if (override.newBareSpecifier.startsWith('link:')) {
protocol = 'link:'
} else {
return undefined
}
const pkgPath = override.newPref.substring(protocol.length)
const pkgPath = override.newBareSpecifier.substring(protocol.length)
const specifiedViaRelativePath = !path.isAbsolute(pkgPath)
const absolutePath = specifiedViaRelativePath ? path.join(rootDir, pkgPath) : pkgPath
return { absolutePath, specifiedViaRelativePath, protocol }
@@ -90,23 +90,23 @@ function overrideDeps (
deps: Dependencies,
peerDeps: Dependencies | undefined
): void {
for (const [name, pref] of Object.entries(peerDeps ?? deps)) {
for (const [name, bareSpecifier] of Object.entries(peerDeps ?? deps)) {
const versionOverride =
pickMostSpecificVersionOverride(
versionOverrides.filter(
({ targetPkg }) =>
targetPkg.name === name && isIntersectingRange(targetPkg.pref, pref)
targetPkg.name === name && isIntersectingRange(targetPkg.bareSpecifier, bareSpecifier)
)
) ??
pickMostSpecificVersionOverride(
genericVersionOverrides.filter(
({ targetPkg }) =>
targetPkg.name === name && isIntersectingRange(targetPkg.pref, pref)
targetPkg.name === name && isIntersectingRange(targetPkg.bareSpecifier, bareSpecifier)
)
)
if (!versionOverride) continue
if (versionOverride.newPref === '-') {
if (versionOverride.newBareSpecifier === '-') {
if (peerDeps) {
delete peerDeps[versionOverride.targetPkg.name]
} else {
@@ -115,13 +115,13 @@ function overrideDeps (
continue
}
const newPref = versionOverride.localTarget
const newBareSpecifier = versionOverride.localTarget
? `${versionOverride.localTarget.protocol}${resolveLocalOverride(versionOverride.localTarget, dir)}`
: versionOverride.newPref
if (peerDeps == null || !isValidPeerRange(newPref)) {
deps[versionOverride.targetPkg.name] = newPref
} else if (isValidPeerRange(newPref)) {
peerDeps[versionOverride.targetPkg.name] = newPref
: versionOverride.newBareSpecifier
if (peerDeps == null || !isValidPeerRange(newBareSpecifier)) {
deps[versionOverride.targetPkg.name] = newBareSpecifier
} else if (isValidPeerRange(newBareSpecifier)) {
peerDeps[versionOverride.targetPkg.name] = newBareSpecifier
}
}
}
@@ -133,5 +133,5 @@ function resolveLocalOverride ({ specifiedViaRelativePath, absolutePath }: Local
}
function pickMostSpecificVersionOverride (versionOverrides: VersionOverride[]): VersionOverride | undefined {
return versionOverrides.sort((a, b) => isIntersectingRange(b.targetPkg.pref ?? '', a.targetPkg.pref ?? '') ? -1 : 1)[0]
return versionOverrides.sort((a, b) => isIntersectingRange(b.targetPkg.bareSpecifier ?? '', a.targetPkg.bareSpecifier ?? '') ? -1 : 1)[0]
}

View File

@@ -32,7 +32,7 @@ test('createReadPackageHook() runs the custom hook before the version overrider'
targetPkg: {
name: 'react',
},
newPref: '16',
newBareSpecifier: '16',
},
],
})

View File

@@ -6,16 +6,16 @@ test('createVersionsOverrider() matches sub-ranges', () => {
{
targetPkg: {
name: 'foo',
pref: '2',
bareSpecifier: '2',
},
newPref: '2.12.0',
newBareSpecifier: '2.12.0',
},
{
targetPkg: {
name: 'qar',
pref: '>2',
bareSpecifier: '>2',
},
newPref: '1.0.0',
newBareSpecifier: '1.0.0',
},
], process.cwd())
expect(
@@ -34,16 +34,16 @@ test('createVersionsOverrider() does not fail on non-range selectors', () => {
{
targetPkg: {
name: 'foo',
pref: '2',
bareSpecifier: '2',
},
newPref: '2.12.0',
newBareSpecifier: '2.12.0',
},
{
targetPkg: {
name: 'bar',
pref: 'github:org/bar',
bareSpecifier: 'github:org/bar',
},
newPref: '2.12.0',
newBareSpecifier: '2.12.0',
},
], process.cwd())
expect(
@@ -66,24 +66,24 @@ test('createVersionsOverrider() overrides dependencies of specified packages onl
{
parentPkg: {
name: 'foo',
pref: '1',
bareSpecifier: '1',
},
targetPkg: {
name: 'bar',
pref: '^1.2.0',
bareSpecifier: '^1.2.0',
},
newPref: '3.0.0',
newBareSpecifier: '3.0.0',
},
{
parentPkg: {
name: 'qar',
pref: '1',
bareSpecifier: '1',
},
targetPkg: {
name: 'bar',
pref: '>4',
bareSpecifier: '>4',
},
newPref: '3.0.0',
newBareSpecifier: '3.0.0',
},
], process.cwd())
expect(overrider({
@@ -146,19 +146,19 @@ test('createVersionsOverrider() overrides all types of dependencies', () => {
targetPkg: {
name: 'foo',
},
newPref: '3.0.0',
newBareSpecifier: '3.0.0',
},
{
targetPkg: {
name: 'bar',
},
newPref: '3.0.0',
newBareSpecifier: '3.0.0',
},
{
targetPkg: {
name: 'qar',
},
newPref: '3.0.0',
newBareSpecifier: '3.0.0',
},
], process.cwd())
expect(overrider({
@@ -194,7 +194,7 @@ test('createVersionsOverrider() overrides dependencies with links', () => {
targetPkg: {
name: 'qar',
},
newPref: 'link:../qar',
newBareSpecifier: 'link:../qar',
},
], process.cwd())
expect(overrider({
@@ -219,7 +219,7 @@ test('createVersionsOverrider() overrides dependencies with absolute links', ()
targetPkg: {
name: 'qar',
},
newPref: `link:${qarAbsolutePath}`,
newBareSpecifier: `link:${qarAbsolutePath}`,
},
], process.cwd())
@@ -243,12 +243,12 @@ test('createVersionsOverrider() overrides dependency of pkg matched by name and
{
parentPkg: {
name: 'yargs',
pref: '^7.1.0',
bareSpecifier: '^7.1.0',
},
targetPkg: {
name: 'yargs-parser',
},
newPref: '^20.0.0',
newBareSpecifier: '^20.0.0',
},
], process.cwd())
expect(
@@ -273,12 +273,12 @@ test('createVersionsOverrider() does not override dependency of pkg matched by n
{
parentPkg: {
name: 'yargs',
pref: '^8.1.0',
bareSpecifier: '^8.1.0',
},
targetPkg: {
name: 'yargs-parser',
},
newPref: '^20.0.0',
newBareSpecifier: '^20.0.0',
},
], process.cwd())
expect(
@@ -307,7 +307,7 @@ test('createVersionsOverrider() should work for scoped parent and unscoped child
targetPkg: {
name: 'unscoped-package',
},
newPref: 'workspace:*',
newBareSpecifier: 'workspace:*',
},
], process.cwd())
expect(
@@ -336,7 +336,7 @@ test('createVersionsOverrider() should work for unscoped parent and scoped child
targetPkg: {
name: '@scoped/package',
},
newPref: 'workspace:*',
newBareSpecifier: 'workspace:*',
},
], process.cwd())
expect(
@@ -365,7 +365,7 @@ test('createVersionsOverrider() should work for scoped parent and scoped child',
targetPkg: {
name: '@scoped/package2',
},
newPref: 'workspace:*',
newBareSpecifier: 'workspace:*',
},
], process.cwd())
expect(
@@ -392,7 +392,7 @@ test('createVersionsOverrider() overrides dependencies with file with relative p
targetPkg: {
name: 'qar',
},
newPref: 'file:../qar',
newBareSpecifier: 'file:../qar',
},
], rootDir)
expect(overrider({
@@ -417,7 +417,7 @@ test('createVersionsOverrider() overrides dependencies with file with relative p
targetPkg: {
name: 'qar',
},
newPref: 'file:../qar',
newBareSpecifier: 'file:../qar',
},
], rootDir)
expect(overrider({
@@ -442,7 +442,7 @@ test('createVersionsOverrider() overrides dependencies with file specified with
targetPkg: {
name: 'qar',
},
newPref: `file:${absolutePath}`,
newBareSpecifier: `file:${absolutePath}`,
},
], process.cwd())
expect(overrider({
@@ -466,21 +466,21 @@ test('createVersionOverride() should use the most specific rule when both overri
targetPkg: {
name: 'foo',
},
newPref: '3.0.0',
newBareSpecifier: '3.0.0',
},
{
targetPkg: {
name: 'foo',
pref: '3',
bareSpecifier: '3',
},
newPref: '4.0.0',
newBareSpecifier: '4.0.0',
},
{
targetPkg: {
name: 'foo',
pref: '2',
bareSpecifier: '2',
},
newPref: '2.12.0',
newBareSpecifier: '2.12.0',
},
{
parentPkg: {
@@ -488,9 +488,9 @@ test('createVersionOverride() should use the most specific rule when both overri
},
targetPkg: {
name: 'foo',
pref: '2',
bareSpecifier: '2',
},
newPref: 'github:org/foo',
newBareSpecifier: 'github:org/foo',
},
{
parentPkg: {
@@ -498,9 +498,9 @@ test('createVersionOverride() should use the most specific rule when both overri
},
targetPkg: {
name: 'foo',
pref: '3',
bareSpecifier: '3',
},
newPref: '5.0.0',
newBareSpecifier: '5.0.0',
},
], process.cwd())
expect(
@@ -573,9 +573,9 @@ test('createVersionsOverrider() matches intersections', () => {
{
targetPkg: {
name: 'foo',
pref: '<1.2.4',
bareSpecifier: '<1.2.4',
},
newPref: '>=1.2.4',
newBareSpecifier: '>=1.2.4',
},
], process.cwd())
expect(
@@ -596,7 +596,7 @@ test('createVersionsOverrider() overrides peerDependencies of another dependency
targetPkg: {
name: 'react',
},
newPref: '18.1.0',
newBareSpecifier: '18.1.0',
},
], process.cwd())
expect(
@@ -623,7 +623,7 @@ test('createVersionsOverrider() removes dependencies', () => {
targetPkg: {
name: 'foo',
},
newPref: '-',
newBareSpecifier: '-',
},
{
parentPkg: {
@@ -632,14 +632,14 @@ test('createVersionsOverrider() removes dependencies', () => {
targetPkg: {
name: 'baz',
},
newPref: '-',
newBareSpecifier: '-',
},
{
targetPkg: {
name: 'qux',
pref: '2',
bareSpecifier: '2',
},
newPref: '-',
newBareSpecifier: '-',
},
], process.cwd())
expect(
@@ -697,19 +697,19 @@ test('createVersionsOverrider() moves invalid versions from peerDependencies to
targetPkg: {
name: 'foo',
},
newPref: 'link:foo',
newBareSpecifier: 'link:foo',
},
{
targetPkg: {
name: 'bar',
},
newPref: 'file:bar',
newBareSpecifier: 'file:bar',
},
{
targetPkg: {
name: 'baz',
},
newPref: '7.7.7',
newBareSpecifier: '7.7.7',
},
], process.cwd())
expect(

View File

@@ -3,8 +3,8 @@ import { type VersionOverride } from '@pnpm/parse-overrides'
export function createOverridesMapFromParsed (parsedOverrides: VersionOverride[] | undefined): Record<string, string> {
if (!parsedOverrides) return {}
const overridesMap: Record<string, string> = {}
for (const { selector, newPref } of parsedOverrides) {
overridesMap[selector] = newPref
for (const { selector, newBareSpecifier } of parsedOverrides) {
overridesMap[selector] = newBareSpecifier
}
return overridesMap
}

View File

@@ -25,7 +25,7 @@ export type SkippedOptionalDependencyMessage = {
id?: never
name: string | undefined
version: string | undefined
pref: string
bareSpecifier: string
}
reason: 'resolution_failure'
})

View File

@@ -3,7 +3,7 @@ import { type LogLevel } from './LogLevel'
export interface OptionalErrorProperties {
pkgsStack?: Array<{ id: string, name: string, version: string }>
hint?: string
package?: { name?: string, pref?: string, version?: string }
package?: { name?: string, bareSpecifier?: string, version?: string }
err?: NodeJS.ErrnoException
}

View File

@@ -2,12 +2,12 @@ import validateNpmPackageName from 'validate-npm-package-name'
export interface ParsedWantedDependency {
alias: string
pref: string
bareSpecifier: string
}
export type ParseWantedDependencyResult = Partial<ParsedWantedDependency> &
(
Omit<ParsedWantedDependency, 'pref'>
Omit<ParsedWantedDependency, 'bareSpecifier'>
| Omit<ParsedWantedDependency, 'alias'>
| ParsedWantedDependency
)
@@ -19,11 +19,11 @@ export function parseWantedDependency (rawWantedDependency: string): ParseWanted
if (validateNpmPackageName(alias).validForOldPackages) {
return {
alias,
pref: rawWantedDependency.slice(versionDelimiter + 1),
bareSpecifier: rawWantedDependency.slice(versionDelimiter + 1),
}
}
return {
pref: rawWantedDependency,
bareSpecifier: rawWantedDependency,
}
}
if (validateNpmPackageName(rawWantedDependency).validForOldPackages) {
@@ -32,6 +32,6 @@ export function parseWantedDependency (rawWantedDependency: string): ParseWanted
}
}
return {
pref: rawWantedDependency,
bareSpecifier: rawWantedDependency,
}
}

View File

@@ -46,8 +46,8 @@ export function renderPeerIssues (
if (currentParentPkg && allowedVersionsByParentPkgName[peerName]?.[currentParentPkg.name]) {
const allowedVersionsByParent: Record<string, string[]> = {}
for (const { targetPkg, parentPkg, ranges } of allowedVersionsByParentPkgName[peerName][currentParentPkg.name]) {
if (!parentPkg.pref || currentParentPkg.version &&
(isSubRange(parentPkg.pref, currentParentPkg.version) || semver.satisfies(currentParentPkg.version, parentPkg.pref))) {
if (!parentPkg.bareSpecifier || currentParentPkg.version &&
(isSubRange(parentPkg.bareSpecifier, currentParentPkg.version) || semver.satisfies(currentParentPkg.version, parentPkg.bareSpecifier))) {
allowedVersionsByParent[targetPkg.name] = ranges
}
}
@@ -153,8 +153,8 @@ function parseAllowedVersions (allowedVersions: Record<string, string>): ParsedA
const overrides = tryParseAllowedVersions(allowedVersions)
const allowedVersionsMatchAll: Record<string, string[]> = {}
const allowedVersionsByParentPkgName: AllowedVersionsByParentPkgName = {}
for (const { parentPkg, targetPkg, newPref } of overrides) {
const ranges = parseVersions(newPref)
for (const { parentPkg, targetPkg, newBareSpecifier } of overrides) {
const ranges = parseVersions(newBareSpecifier)
if (!parentPkg) {
allowedVersionsMatchAll[targetPkg.name] = ranges
continue

View File

@@ -11,9 +11,9 @@ export function getEditDirPath (param: string, patchedDep: ParseWantedDependency
}
function getEditDirNameFromParsedDep (patchedDep: ParseWantedDependencyResult): string | undefined {
if (patchedDep.alias && patchedDep.pref) {
const pref = patchedDep.pref.replace(/[\\/:*?"<>|]+/g, '+')
return `${patchedDep.alias}@${pref}`
if (patchedDep.alias && patchedDep.bareSpecifier) {
const bareSpecifier = patchedDep.bareSpecifier.replace(/[\\/:*?"<>|]+/g, '+')
return `${patchedDep.alias}@${bareSpecifier}`
}
if (patchedDep.alias) {

View File

@@ -55,14 +55,14 @@ export async function getPatchedDependency (rawDependency: string, opts: GetPatc
return {
...dep,
applyToAll,
pref: version,
bareSpecifier: version,
}
} else {
const preferred = preferredVersions[0]
return {
...dep,
applyToAll: !dep.pref,
pref: preferred.gitTarballUrl ?? preferred.version,
applyToAll: !dep.bareSpecifier,
bareSpecifier: preferred.gitTarballUrl ?? preferred.version,
}
}
}
@@ -96,7 +96,7 @@ export async function getVersionsFromLockfile (dep: ParseWantedDependencyResult,
)
}
const pkgName = dep.alias && dep.pref ? dep.alias : (dep.pref ?? dep.alias)
const pkgName = dep.alias && dep.bareSpecifier ? dep.alias : (dep.bareSpecifier ?? dep.alias)
const versions = Object.entries(lockfile.packages ?? {})
.map(([depPath, pkgSnapshot]) => {
@@ -110,6 +110,6 @@ export async function getVersionsFromLockfile (dep: ParseWantedDependencyResult,
return {
versions,
preferredVersions: versions.filter(({ version }) => dep.alias && dep.pref ? semver.satisfies(version, dep.pref) : true),
preferredVersions: versions.filter(({ version }) => dep.alias && dep.bareSpecifier ? semver.satisfies(version, dep.bareSpecifier) : true),
}
}

View File

@@ -130,7 +130,7 @@ To commit your changes, run:
function tryPatchWithExistingPatchFile (
{
allowFailure,
patchedDep: { applyToAll, alias, pref },
patchedDep: { applyToAll, alias, bareSpecifier },
patchedDir,
patchedDependencies,
lockfileDir,
@@ -144,8 +144,8 @@ function tryPatchWithExistingPatchFile (
): void {
if (!alias) return
let existingPatchFile: string | undefined
if (pref) {
existingPatchFile = patchedDependencies[`${alias}@${pref}`]
if (bareSpecifier) {
existingPatchFile = patchedDependencies[`${alias}@${bareSpecifier}`]
}
if (!existingPatchFile && applyToAll) {
existingPatchFile = patchedDependencies[alias]

View File

@@ -74,7 +74,7 @@ export async function handler (opts: PatchCommitCommandOptions, params: string[]
if (!applyToAll) {
gitTarballUrl = await getGitTarballUrlFromLockfile({
alias: patchedPkgManifest.name,
pref: patchedPkgManifest.version,
bareSpecifier: patchedPkgManifest.version,
}, {
lockfileDir,
modulesDir: opts.modulesDir,

View File

@@ -4,27 +4,27 @@ import { getEditDirPath } from '../src/getEditDirPath'
test('getEditDirPath() returns path to pkg@version inside node_modules/.pnpm_patches', () => {
expect(getEditDirPath('pkg', {
alias: 'pkg',
pref: '0.1.2',
bareSpecifier: '0.1.2',
}, { modulesDir: 'node_modules' })).toBe(path.join('node_modules', '.pnpm_patches', 'pkg@0.1.2'))
})
test('getEditDirPath() returns path to pkg@version inside .pnpm_patches inside specified modules dir', () => {
expect(getEditDirPath('pkg', {
alias: 'pkg',
pref: '0.1.2',
bareSpecifier: '0.1.2',
}, {
modulesDir: 'user-defined-modules-dir',
})).toBe(path.join('user-defined-modules-dir', '.pnpm_patches', 'pkg@0.1.2'))
})
test('getEditDirPath() returns valid path even if pref contains special characters', () => {
test('getEditDirPath() returns valid path even if bareSpecifier contains special characters', () => {
expect(getEditDirPath('pkg', {
alias: 'pkg',
pref: 'https://codeload.github.com/zkochan/hi/tar.gz',
bareSpecifier: 'https://codeload.github.com/zkochan/hi/tar.gz',
}, { modulesDir: 'node_modules' })).toBe(path.join('node_modules', '.pnpm_patches', 'pkg@https+codeload.github.com+zkochan+hi+tar.gz'))
})
test('getEditDirPath() returns path with name of alias if pref is not available', () => {
test('getEditDirPath() returns path with name of alias if bareSpecifier is not available', () => {
expect(getEditDirPath('pkg', {
alias: 'resolved-pkg',
}, { modulesDir: 'node_modules' })).toBe(path.join('node_modules', '.pnpm_patches', 'resolved-pkg'))
@@ -32,6 +32,6 @@ test('getEditDirPath() returns path with name of alias if pref is not available'
test('getEditDirPath() returns path with name of param if alias is not available', () => {
expect(getEditDirPath('pkg', {
pref: '0.1.2',
bareSpecifier: '0.1.2',
}, { modulesDir: 'node_modules' })).toBe(path.join('node_modules', '.pnpm_patches', 'pkg'))
})

View File

@@ -92,7 +92,7 @@ export interface StrictInstallOptions {
strictPeerDependencies: boolean
include: IncludedDependencies
includeDirect: IncludedDependencies
ignoreCurrentPrefs: boolean
ignoreCurrentSpecifiers: boolean
ignoreScripts: boolean
childConcurrency: number
userAgent: string
@@ -186,7 +186,7 @@ const defaults = (opts: InstallOptions): StrictInstallOptions => {
hoistPattern: undefined,
publicHoistPattern: undefined,
hooks: {},
ignoreCurrentPrefs: false,
ignoreCurrentSpecifiers: false,
ignoreDepScripts: false,
ignoreScripts: false,
include: {

View File

@@ -390,7 +390,7 @@ export async function mutateModules (
throw new LockfileConfigMismatchError(outdatedLockfileSettingName!)
}
}
const _isWantedDepPrefSame = isWantedDepPrefSame.bind(null, ctx.wantedLockfile.catalogs, opts.catalogs)
const _isWantedDepBareSpecifierSame = isWantedDepBareSpecifierSame.bind(null, ctx.wantedLockfile.catalogs, opts.catalogs)
const upToDateLockfileMajorVersion = ctx.wantedLockfile.lockfileVersion.toString().startsWith(`${LOCKFILE_MAJOR_VERSION}.`)
let needsFullResolution = outdatedLockfileSettings ||
opts.fixLockfile ||
@@ -479,7 +479,7 @@ export async function mutateModules (
.map((wantedDependency) => ({ ...wantedDependency, updateSpec: true }))
if (ctx.wantedLockfile?.importers) {
forgetResolutionsOfPrevWantedDeps(ctx.wantedLockfile.importers[project.id], wantedDependencies, _isWantedDepPrefSame)
forgetResolutionsOfPrevWantedDeps(ctx.wantedLockfile.importers[project.id], wantedDependencies, _isWantedDepBareSpecifierSame)
}
if (opts.ignoreScripts && project.manifest?.scripts &&
(project.manifest.scripts.preinstall ||
@@ -498,7 +498,7 @@ export async function mutateModules (
}
async function installSome (project: any) { // eslint-disable-line
const currentPrefs = opts.ignoreCurrentPrefs ? {} : getAllDependenciesFromManifest(project.manifest)
const currentBareSpecifiers = opts.ignoreCurrentSpecifiers ? {} : getAllDependenciesFromManifest(project.manifest)
const optionalDependencies = project.targetDependenciesField ? {} : project.manifest.optionalDependencies || {}
const devDependencies = project.targetDependenciesField ? {} : project.manifest.devDependencies || {}
if (preferredSpecs == null) {
@@ -512,7 +512,7 @@ export async function mutateModules (
}
const wantedDeps = parseWantedDependencies(project.dependencySelectors, {
allowNew: project.allowNew !== false,
currentPrefs,
currentBareSpecifiers,
defaultTag: opts.tag,
dev: project.targetDependenciesField === 'devDependencies',
devDependencies,
@@ -526,7 +526,7 @@ export async function mutateModules (
projectsToInstall.push({
pruneDirectDependencies: false,
...project,
wantedDependencies: wantedDeps.map(wantedDep => ({ ...wantedDep, isNew: !currentPrefs[wantedDep.alias], updateSpec: true, nodeExecPath: opts.nodeExecPath })),
wantedDependencies: wantedDeps.map(wantedDep => ({ ...wantedDep, isNew: !currentBareSpecifiers[wantedDep.alias], updateSpec: true, nodeExecPath: opts.nodeExecPath })),
})
}
@@ -770,14 +770,14 @@ function pkgHasDependencies (manifest: ProjectManifest): boolean {
function forgetResolutionsOfPrevWantedDeps (
importer: ProjectSnapshot,
wantedDeps: WantedDependency[],
isWantedDepPrefSame: (alias: string, prevPref: string | undefined, nextPref: string) => boolean
isWantedDepBareSpecifierSame: (alias: string, prevBareSpecifier: string | undefined, nextBareSpecifier: string) => boolean
): void {
if (!importer.specifiers) return
importer.dependencies = importer.dependencies ?? {}
importer.devDependencies = importer.devDependencies ?? {}
importer.optionalDependencies = importer.optionalDependencies ?? {}
for (const { alias, pref } of wantedDeps) {
if (alias && !isWantedDepPrefSame(alias, importer.specifiers[alias], pref)) {
for (const { alias, bareSpecifier } of wantedDeps) {
if (alias && !isWantedDepBareSpecifierSame(alias, importer.specifiers[alias], bareSpecifier)) {
if (!importer.dependencies[alias]?.startsWith('link:')) {
delete importer.dependencies[alias]
}
@@ -809,31 +809,31 @@ function forgetResolutionsOfAllPrevWantedDeps (wantedLockfile: LockfileObject):
}
/**
* Check if a wanted pref is the same.
* Check if a wanted bareSpecifier is the same.
*
* It would be different if the user modified a dependency in package.json or a
* catalog entry in pnpm-workspace.yaml. This is normally a simple check to see
* if the specifier strings match, but catalogs make this more involved since we
* also have to check if the catalog config in pnpm-workspace.yaml is the same.
*/
function isWantedDepPrefSame (
function isWantedDepBareSpecifierSame (
prevCatalogs: CatalogSnapshots | undefined,
catalogsConfig: Catalogs | undefined,
alias: string,
prevPref: string | undefined,
nextPref: string
prevBareSpecifier: string | undefined,
nextBareSpecifier: string
): boolean {
if (prevPref !== nextPref) {
if (prevBareSpecifier !== nextBareSpecifier) {
return false
}
// When pnpm catalogs are used, the specifiers can be the same (e.g.
// "catalog:default"), but the wanted versions for the dependency can be
// different after resolution if the catalog config was just edited.
const catalogName = parseCatalogProtocol(prevPref)
const catalogName = parseCatalogProtocol(prevBareSpecifier)
// If there's no catalog name, the catalog protocol was not used and we
// can assume the pref is the same since prevPref and nextPref match.
// can assume the bareSpecifier is the same since prevBareSpecifier and nextBareSpecifier match.
if (catalogName === null) {
return true
}
@@ -1447,7 +1447,7 @@ const installInContext: InstallFunction = async (projects, ctx, opts) => {
nodeExecPath: opts.nodeExecPath,
injectWorkspacePackages: opts.injectWorkspacePackages,
}
const _isWantedDepPrefSame = isWantedDepPrefSame.bind(null, ctx.wantedLockfile.catalogs, opts.catalogs)
const _isWantedDepBareSpecifierSame = isWantedDepBareSpecifierSame.bind(null, ctx.wantedLockfile.catalogs, opts.catalogs)
for (const project of allProjectsLocatedInsideWorkspace) {
if (!newProjects.some(({ rootDir }) => rootDir === project.rootDir)) {
// This code block mirrors the installCase() function in
@@ -1455,7 +1455,7 @@ const installInContext: InstallFunction = async (projects, ctx, opts) => {
// deduplicate code.
const wantedDependencies = getWantedDependencies(project.manifest, getWantedDepsOpts)
.map((wantedDependency) => ({ ...wantedDependency, updateSpec: true, preserveNonSemverVersionSpec: true }))
forgetResolutionsOfPrevWantedDeps(ctx.wantedLockfile.importers[project.id], wantedDependencies, _isWantedDepPrefSame)
forgetResolutionsOfPrevWantedDeps(ctx.wantedLockfile.importers[project.id], wantedDependencies, _isWantedDepBareSpecifierSame)
newProjects.push({
mutation: 'install',
...project,

View File

@@ -7,7 +7,7 @@ export function parseWantedDependencies (
rawWantedDependencies: string[],
opts: {
allowNew: boolean
currentPrefs: Dependencies
currentBareSpecifiers: Dependencies
defaultTag: string
dev: boolean
devDependencies: Dependencies
@@ -23,48 +23,48 @@ export function parseWantedDependencies (
.map((rawWantedDependency) => {
const parsed = parseWantedDependency(rawWantedDependency)
const alias = parsed['alias']
let pref = parsed['pref']
let bareSpecifier = parsed['bareSpecifier']
if (!opts.allowNew && (!alias || !opts.currentPrefs[alias])) {
if (!opts.allowNew && (!alias || !opts.currentBareSpecifiers[alias])) {
return null
}
if (alias && opts.defaultCatalog?.[alias] && (
(!opts.currentPrefs[alias] && pref === undefined) ||
opts.defaultCatalog[alias] === pref ||
opts.defaultCatalog[alias] === opts.currentPrefs[alias]
(!opts.currentBareSpecifiers[alias] && bareSpecifier === undefined) ||
opts.defaultCatalog[alias] === bareSpecifier ||
opts.defaultCatalog[alias] === opts.currentBareSpecifiers[alias]
)) {
pref = 'catalog:'
bareSpecifier = 'catalog:'
}
if (alias && opts.currentPrefs[alias]) {
pref ??= opts.currentPrefs[alias]
if (alias && opts.currentBareSpecifiers[alias]) {
bareSpecifier ??= opts.currentBareSpecifiers[alias]
}
const result = {
alias,
dev: Boolean(opts.dev || alias && !!opts.devDependencies[alias]),
optional: Boolean(opts.optional || alias && !!opts.optionalDependencies[alias]),
prevSpecifier: alias && opts.currentPrefs[alias],
prevSpecifier: alias && opts.currentBareSpecifiers[alias],
}
if (pref) {
if (bareSpecifier) {
return {
...result,
pref,
bareSpecifier,
}
}
if (alias && opts.preferredSpecs?.[alias]) {
return {
...result,
pref: opts.preferredSpecs[alias],
bareSpecifier: opts.preferredSpecs[alias],
}
}
if (alias && opts.overrides?.[alias]) {
return {
...result,
pref: opts.overrides[alias],
bareSpecifier: opts.overrides[alias],
}
}
return {
...result,
pref: opts.defaultTag,
bareSpecifier: opts.defaultTag,
}
})
.filter((wd) => wd !== null) as WantedDependency[]

View File

@@ -161,7 +161,7 @@ async function resolveAndFetch (
): Promise<PackageResponse> {
let latest: string | undefined
let manifest: DependencyManifest | undefined
let specifier: string | undefined
let normalizedBareSpecifier: string | undefined
let alias: string | undefined
let resolution = options.currentPkg?.resolution as Resolution
let pkgId = options.currentPkg?.id
@@ -209,7 +209,7 @@ async function resolveAndFetch (
updated = pkgId !== resolveResult.id || !resolution || forceFetch
resolution = resolveResult.resolution
pkgId = resolveResult.id
specifier = resolveResult.specifier
normalizedBareSpecifier = resolveResult.normalizedBareSpecifier
alias = resolveResult.alias
}
@@ -217,7 +217,7 @@ async function resolveAndFetch (
if (resolution.type === 'directory' && !id.startsWith('file:')) {
if (manifest == null) {
throw new Error(`Couldn't read package.json of local dependency ${wantedDependency.alias ? wantedDependency.alias + '@' : ''}${wantedDependency.pref ?? ''}`)
throw new Error(`Couldn't read package.json of local dependency ${wantedDependency.alias ? wantedDependency.alias + '@' : ''}${wantedDependency.bareSpecifier ?? ''}`)
}
return {
body: {
@@ -227,7 +227,7 @@ async function resolveAndFetch (
resolution: resolution as DirectoryResolution,
resolvedVia,
updated,
specifier,
normalizedBareSpecifier,
alias,
},
}
@@ -257,7 +257,7 @@ async function resolveAndFetch (
isInstallable: isInstallable ?? undefined,
latest,
manifest,
specifier,
normalizedBareSpecifier,
resolution,
resolvedVia,
updated,
@@ -294,7 +294,7 @@ async function resolveAndFetch (
isInstallable: isInstallable ?? undefined,
latest,
manifest,
specifier,
normalizedBareSpecifier,
resolution,
resolvedVia,
updated,

View File

@@ -47,7 +47,7 @@ test('request package', async () => {
expect(typeof requestPackage).toBe('function')
const projectDir = tempy.directory()
const pkgResponse = await requestPackage({ alias: 'is-positive', pref: '1.0.0' }, {
const pkgResponse = await requestPackage({ alias: 'is-positive', bareSpecifier: '1.0.0' }, {
downloadPriority: 0,
lockfileDir: projectDir,
preferredVersions: {},
@@ -62,7 +62,7 @@ test('request package', async () => {
expect(pkgResponse.body.isLocal).toBe(false)
expect(typeof pkgResponse.body.latest).toBe('string')
expect(pkgResponse.body.manifest?.name).toBe('is-positive')
expect(!pkgResponse.body.specifier).toBeTruthy()
expect(!pkgResponse.body.normalizedBareSpecifier).toBeTruthy()
expect(pkgResponse.body.resolution).toStrictEqual({
integrity: 'sha512-xxzPGZ4P2uN6rROUa5N9Z7zTX6ERuE0hs6GUOc/cKBLF2NqKc16UwqHMt3tFg4CO6EBTE5UecUasg+3jZx3Ckg==',
tarball: `http://localhost:${REGISTRY_MOCK_PORT}/is-positive/-/is-positive-1.0.0.tgz`,
@@ -88,7 +88,7 @@ test('request package but skip fetching', async () => {
expect(typeof requestPackage).toBe('function')
const projectDir = tempy.directory()
const pkgResponse = await requestPackage({ alias: 'is-positive', pref: '1.0.0' }, {
const pkgResponse = await requestPackage({ alias: 'is-positive', bareSpecifier: '1.0.0' }, {
downloadPriority: 0,
lockfileDir: projectDir,
preferredVersions: {},
@@ -103,7 +103,7 @@ test('request package but skip fetching', async () => {
expect(pkgResponse.body.isLocal).toBe(false)
expect(typeof pkgResponse.body.latest).toBe('string')
expect(pkgResponse.body.manifest?.name).toBe('is-positive')
expect(!pkgResponse.body.specifier).toBeTruthy()
expect(!pkgResponse.body.normalizedBareSpecifier).toBeTruthy()
expect(pkgResponse.body.resolution).toStrictEqual({
integrity: 'sha512-xxzPGZ4P2uN6rROUa5N9Z7zTX6ERuE0hs6GUOc/cKBLF2NqKc16UwqHMt3tFg4CO6EBTE5UecUasg+3jZx3Ckg==',
tarball: `http://localhost:${REGISTRY_MOCK_PORT}/is-positive/-/is-positive-1.0.0.tgz`,
@@ -127,7 +127,7 @@ test('request package but skip fetching, when resolution is already available',
expect(typeof requestPackage).toBe('function')
const projectDir = tempy.directory()
const pkgResponse = await requestPackage({ alias: 'is-positive', pref: '1.0.0' }, {
const pkgResponse = await requestPackage({ alias: 'is-positive', bareSpecifier: '1.0.0' }, {
currentPkg: {
id: 'is-positive@1.0.0' as PkgResolutionId,
resolution: {
@@ -155,7 +155,7 @@ test('request package but skip fetching, when resolution is already available',
expect(pkgResponse.body.isLocal).toBe(false)
expect(typeof pkgResponse.body.latest).toBe('string')
expect(pkgResponse.body.manifest.name).toBe('is-positive')
expect(!pkgResponse.body.specifier).toBeTruthy()
expect(!pkgResponse.body.normalizedBareSpecifier).toBeTruthy()
expect(pkgResponse.body.resolution).toStrictEqual({
integrity: 'sha512-xxzPGZ4P2uN6rROUa5N9Z7zTX6ERuE0hs6GUOc/cKBLF2NqKc16UwqHMt3tFg4CO6EBTE5UecUasg+3jZx3Ckg==',
tarball: `http://localhost:${REGISTRY_MOCK_PORT}/is-positive/-/is-positive-1.0.0.tgz`,
@@ -170,7 +170,7 @@ test('refetch local tarball if its integrity has changed', async () => {
const tarballRelativePath = path.relative(projectDir, tarballPath)
f.copy('pnpm-package-requester-0.8.1.tgz', tarballPath)
const tarball = `file:${tarballRelativePath}`
const wantedPackage = { pref: tarball }
const wantedPackage = { bareSpecifier: tarball }
const storeDir = tempy.directory()
const cafs = createCafsStore(storeDir)
const pkgId = `file:${normalize(tarballRelativePath)}`
@@ -277,7 +277,7 @@ test('refetch local tarball if its integrity has changed. The requester does not
const tarballPath = path.join(projectDir, 'tarball.tgz')
f.copy('pnpm-package-requester-0.8.1.tgz', tarballPath)
const tarball = `file:${tarballPath}`
const wantedPackage = { pref: tarball }
const wantedPackage = { bareSpecifier: tarball }
const storeDir = path.join(projectDir, 'store')
const cafs = createCafsStore(storeDir)
const requestPackageOpts = {
@@ -572,7 +572,7 @@ test('always return a package manifest in the response', async () => {
const projectDir = tempy.directory()
{
const pkgResponse = await requestPackage({ alias: 'is-positive', pref: '1.0.0' }, {
const pkgResponse = await requestPackage({ alias: 'is-positive', bareSpecifier: '1.0.0' }, {
downloadPriority: 0,
lockfileDir: projectDir,
preferredVersions: {},
@@ -584,7 +584,7 @@ test('always return a package manifest in the response', async () => {
}
{
const pkgResponse = await requestPackage({ alias: 'is-positive', pref: '1.0.0' }, {
const pkgResponse = await requestPackage({ alias: 'is-positive', bareSpecifier: '1.0.0' }, {
currentPkg: {
id: 'is-positive@1.0.0' as PkgResolutionId,
resolution: {
@@ -766,7 +766,7 @@ test('do not fetch an optional package that is not installable', async () => {
expect(typeof requestPackage).toBe('function')
const projectDir = tempy.directory()
const pkgResponse = await requestPackage({ alias: '@pnpm.e2e/not-compatible-with-any-os', optional: true, pref: '*' }, {
const pkgResponse = await requestPackage({ alias: '@pnpm.e2e/not-compatible-with-any-os', optional: true, bareSpecifier: '*' }, {
downloadPriority: 0,
lockfileDir: projectDir,
preferredVersions: {},
@@ -804,7 +804,7 @@ test('fetch a git package without a package.json', async () => {
const projectDir = tempy.directory()
{
const pkgResponse = await requestPackage({ alias: 'camelcase', pref: `${repo}#${commit}` }, {
const pkgResponse = await requestPackage({ alias: 'camelcase', bareSpecifier: `${repo}#${commit}` }, {
downloadPriority: 0,
lockfileDir: projectDir,
preferredVersions: {},
@@ -835,7 +835,7 @@ test('throw exception if the package data in the store differs from the expected
})
const projectDir = tempy.directory()
pkgResponse = await requestPackage({ alias: 'is-positive', pref: '1.0.0' }, {
pkgResponse = await requestPackage({ alias: 'is-positive', bareSpecifier: '1.0.0' }, {
downloadPriority: 0,
lockfileDir: projectDir,
preferredVersions: {},
@@ -971,7 +971,7 @@ test("don't throw an error if the package was updated, so the expectedPkg has a
})
const projectDir = tempy.directory()
const pkgResponse = await requestPackage({ alias: 'is-positive', pref: '3.1.0' }, {
const pkgResponse = await requestPackage({ alias: 'is-positive', bareSpecifier: '3.1.0' }, {
downloadPriority: 0,
lockfileDir: projectDir,
preferredVersions: {},
@@ -989,7 +989,7 @@ test("don't throw an error if the package was updated, so the expectedPkg has a
virtualStoreDirMaxLength: 120,
})
const projectDir = tempy.directory()
const pkgResponse = await requestPackage({ alias: 'is-positive', pref: '3.1.0' }, {
const pkgResponse = await requestPackage({ alias: 'is-positive', bareSpecifier: '3.1.0' }, {
downloadPriority: 0,
lockfileDir: tempy.directory(),
preferredVersions: {},
@@ -1016,7 +1016,7 @@ test('the version in the bundled manifest should be normalized', async () => {
virtualStoreDirMaxLength: 120,
})
const pkgResponse = await requestPackage({ alias: 'react-terminal', pref: '1.2.1' }, {
const pkgResponse = await requestPackage({ alias: 'react-terminal', bareSpecifier: '1.2.1' }, {
downloadPriority: 0,
lockfileDir: tempy.directory(),
preferredVersions: {},
@@ -1046,7 +1046,7 @@ test('should skip store integrity check and resolve manifest if fetchRawManifest
const projectDir = tempy.directory()
pkgResponse = await requestPackage({ alias: 'is-positive', pref: '1.0.0' }, {
pkgResponse = await requestPackage({ alias: 'is-positive', bareSpecifier: '1.0.0' }, {
downloadPriority: 0,
lockfileDir: projectDir,
preferredVersions: {},

View File

@@ -61,7 +61,7 @@ export type InstallDepsOptions = Pick<Config,
| 'global'
| 'globalPnpmfile'
| 'hooks'
| 'ignoreCurrentPrefs'
| 'ignoreCurrentSpecifiers'
| 'ignorePnpmfile'
| 'ignoreScripts'
| 'optimisticRepeatInstall'

View File

@@ -299,7 +299,7 @@ async function update (
...opts,
allowNew: false,
depth,
ignoreCurrentPrefs: false,
ignoreCurrentSpecifiers: false,
includeDirect,
include,
update: true,

View File

@@ -23,8 +23,8 @@ export function createWorkspaceSpecs (specs: string[], workspacePackages: Worksp
const parsed = parseWantedDependency(spec)
if (!parsed.alias) throw new PnpmError('NO_PKG_NAME_IN_SPEC', `Cannot update/install from workspace through "${spec}"`)
if (!workspacePackages.has(parsed.alias)) throw new PnpmError('WORKSPACE_PACKAGE_NOT_FOUND', `"${parsed.alias}" not found in the workspace`)
if (!parsed.pref) return `${parsed.alias}@workspace:*`
if (parsed.pref.startsWith('workspace:')) return spec
return `${parsed.alias}@workspace:${parsed.pref}`
if (!parsed.bareSpecifier) return `${parsed.alias}@workspace:*`
if (parsed.bareSpecifier.startsWith('workspace:')) return spec
return `${parsed.alias}@workspace:${parsed.bareSpecifier}`
})
}

View File

@@ -3,7 +3,7 @@ import pickBy from 'ramda/src/pickBy'
export interface WantedDependency {
alias: string
pref: string // package reference
bareSpecifier: string // package reference
dev: boolean
optional: boolean
injected?: boolean
@@ -37,12 +37,12 @@ function getWantedDependenciesFromGivenSet (
}
): WantedDependency[] {
if (!deps) return []
return Object.entries(deps).map(([alias, pref]) => ({
return Object.entries(deps).map(([alias, bareSpecifier]) => ({
alias,
dev: !!opts.devDependencies[alias],
injected: opts.dependenciesMeta[alias]?.injected,
optional: !!opts.optionalDependencies[alias],
pref,
bareSpecifier,
}))
}

View File

@@ -8,7 +8,7 @@ import {
export interface WantedDependency {
alias: string
pref: string // package reference
bareSpecifier: string // package reference
dev: boolean
optional: boolean
nodeExecPath?: string
@@ -57,7 +57,7 @@ function getWantedDependenciesFromGivenSet (
}
): WantedDependency[] {
if (!deps) return []
return Object.entries(deps).map(([alias, pref]) => {
return Object.entries(deps).map(([alias, bareSpecifier]) => {
let depType
if (opts.optionalDependencies[alias] != null) depType = 'optional'
else if (opts.dependencies[alias] != null) depType = 'prod'
@@ -69,8 +69,8 @@ function getWantedDependenciesFromGivenSet (
injected: opts.dependenciesMeta[alias]?.injected,
optional: depType === 'optional',
nodeExecPath: opts.nodeExecPath ?? opts.dependenciesMeta[alias]?.node,
pref,
prevSpecifier: pref,
bareSpecifier,
prevSpecifier: bareSpecifier,
}
})
}

View File

@@ -0,0 +1,15 @@
import semver from 'semver'
export function replaceVersionInBareSpecifier (bareSpecifier: string, version: string): string {
if (semver.validRange(bareSpecifier)) {
return version
}
if (!bareSpecifier.startsWith('npm:')) {
return bareSpecifier
}
const versionDelimiter = bareSpecifier.lastIndexOf('@')
if (versionDelimiter === -1 || bareSpecifier.indexOf('/') > versionDelimiter) {
return `${bareSpecifier}@${version}`
}
return `${bareSpecifier.substring(0, versionDelimiter + 1)}${version}`
}

View File

@@ -1,15 +0,0 @@
import semver from 'semver'
export function replaceVersionInPref (pref: string, version: string): string {
if (semver.validRange(pref)) {
return version
}
if (!pref.startsWith('npm:')) {
return pref
}
const versionDelimiter = pref.lastIndexOf('@')
if (versionDelimiter === -1 || pref.indexOf('/') > versionDelimiter) {
return `${pref}@${version}`
}
return `${pref.substring(0, versionDelimiter + 1)}${version}`
}

View File

@@ -59,7 +59,7 @@ import { parentIdsContainSequence } from './parentIdsContainSequence'
import { hoistPeers, getHoistableOptionalPeers } from './hoistPeers'
import { wantedDepIsLocallyAvailable } from './wantedDepIsLocallyAvailable'
import { type CatalogLookupMetadata } from './resolveDependencyTree'
import { replaceVersionInPref } from './replaceVersionInPref'
import { replaceVersionInBareSpecifier } from './replaceVersionInBareSpecifier'
const dependencyResolvedLogger = logger('_dependency_resolved')
@@ -113,7 +113,7 @@ export interface LinkedDependency {
name: string
alias: string
catalogLookup?: CatalogLookupMetadata
specifier?: string
normalizedBareSpecifier?: string
}
export interface PendingNode {
@@ -203,7 +203,7 @@ export type PkgAddress = {
publishedAt?: string
catalogLookup?: CatalogLookupMetadata
optional: boolean
specifier?: string
normalizedBareSpecifier?: string
} & ({
isLinkedDependency: true
version: string
@@ -551,10 +551,10 @@ async function resolveDependenciesOfImporterDependency (
throw result.error
},
})
const originalPref = extendedWantedDep.wantedDependency.pref
const originalBareSpecifier = extendedWantedDep.wantedDependency.bareSpecifier
if (catalogLookup != null) {
extendedWantedDep.wantedDependency.pref = getCatalogReplacementPref(
extendedWantedDep.wantedDependency.bareSpecifier = getCatalogReplacementBareSpecifier(
catalogLookup,
ctx.wantedLockfile,
extendedWantedDep.wantedDependency)
@@ -583,7 +583,7 @@ async function resolveDependenciesOfImporterDependency (
if (result.resolveDependencyResult != null && catalogLookup != null) {
result.resolveDependencyResult.catalogLookup = {
...catalogLookup,
userSpecifiedPref: originalPref,
userSpecifiedBareSpecifier: originalBareSpecifier,
}
}
@@ -858,7 +858,7 @@ async function resolveDependenciesOfDependency (
// as an importer separately, and we can rely on that process keeping the
// importers lockfile catalog snapshots up to date.
if (catalogLookup != null) {
extendedWantedDep.wantedDependency.pref = getCatalogReplacementPref(
extendedWantedDep.wantedDependency.bareSpecifier = getCatalogReplacementBareSpecifier(
catalogLookup,
ctx.wantedLockfile,
extendedWantedDep.wantedDependency)
@@ -1065,7 +1065,7 @@ function getDepsToResolve (
// So for example, if foo@1.0.0 had bar@1.0.0 as a dependency
// and foo was updated to 1.1.0 which depends on bar ^1.0.0
// then bar@1.0.0 can be reused for foo@1.1.0
semver.validRange(wantedDependency.pref) !== null &&
semver.validRange(wantedDependency.bareSpecifier) !== null &&
preferredDependencies[wantedDependency.alias] &&
satisfiesWanted(preferredDependencies[wantedDependency.alias])
) {
@@ -1106,7 +1106,7 @@ function referenceSatisfiesWantedSpec (
lockfile: LockfileObject
prefix: string
},
wantedDep: { alias: string, pref: string },
wantedDep: { alias: string, bareSpecifier: string },
preferredRef: string
) {
const depPath = dp.refToRelative(preferredRef, wantedDep.alias)
@@ -1120,10 +1120,10 @@ function referenceSatisfiesWantedSpec (
return false
}
const { version } = nameVerFromPkgSnapshot(depPath, pkgSnapshot)
if (!semver.validRange(wantedDep.pref) && Object.values(opts.lockfile.importers).filter(importer => importer.specifiers[wantedDep.alias] === wantedDep.pref).length) {
if (!semver.validRange(wantedDep.bareSpecifier) && Object.values(opts.lockfile.importers).filter(importer => importer.specifiers[wantedDep.alias] === wantedDep.bareSpecifier).length) {
return true
}
return semver.satisfies(version, wantedDep.pref, true)
return semver.satisfies(version, wantedDep.bareSpecifier, true)
}
type InfoFromLockfile = {
@@ -1260,7 +1260,7 @@ async function resolveDependency (
try {
const calcSpecifier = options.currentDepth === 0
if (!options.update && currentPkg.version && currentPkg.pkgId?.endsWith(`@${currentPkg.version}`) && !calcSpecifier) {
wantedDependency.pref = replaceVersionInPref(wantedDependency.pref, currentPkg.version)
wantedDependency.bareSpecifier = replaceVersionInBareSpecifier(wantedDependency.bareSpecifier, currentPkg.version)
}
pkgResponse = await ctx.storeController.requestPackage(wantedDependency, {
alwaysTryWorkspacePackages: ctx.linkWorkspacePackagesDepth >= options.currentDepth,
@@ -1281,7 +1281,7 @@ async function resolveDependency (
preferWorkspacePackages: ctx.preferWorkspacePackages,
projectDir: (
options.currentDepth > 0 &&
!wantedDependency.pref.startsWith('file:')
!wantedDependency.bareSpecifier.startsWith('file:')
)
? ctx.lockfileDir
: options.parentPkg.rootDir,
@@ -1301,8 +1301,8 @@ async function resolveDependency (
} catch (err: any) { // eslint-disable-line
const wantedDependencyDetails = {
name: wantedDependency.alias,
pref: wantedDependency.pref,
version: wantedDependency.alias ? wantedDependency.pref : undefined,
bareSpecifier: wantedDependency.bareSpecifier,
version: wantedDependency.alias ? wantedDependency.bareSpecifier : undefined,
}
if (wantedDependency.optional) {
skippedOptionalDependencyLogger.debug({
@@ -1325,7 +1325,7 @@ async function resolveDependency (
wanted: {
dependentId: options.parentPkg.pkgId,
name: wantedDependency.alias,
rawSpec: wantedDependency.pref,
rawSpec: wantedDependency.bareSpecifier,
},
})
@@ -1348,7 +1348,7 @@ async function resolveDependency (
if (!pkgResponse.body.manifest) {
// This should actually never happen because the local-resolver returns a manifest
// even if no real manifest exists in the filesystem.
throw new PnpmError('MISSING_PACKAGE_JSON', `Can't install ${wantedDependency.pref}: Missing package.json file`)
throw new PnpmError('MISSING_PACKAGE_JSON', `Can't install ${wantedDependency.bareSpecifier}: Missing package.json file`)
}
return {
alias: wantedDependency.alias ?? pkgResponse.body.alias ?? pkgResponse.body.manifest.name ?? path.basename(pkgResponse.body.resolution.directory),
@@ -1359,7 +1359,7 @@ async function resolveDependency (
pkgId: pkgResponse.body.id,
resolution: pkgResponse.body.resolution,
version: pkgResponse.body.manifest.version,
specifier: pkgResponse.body.specifier,
normalizedBareSpecifier: pkgResponse.body.normalizedBareSpecifier,
}
}
@@ -1389,7 +1389,7 @@ async function resolveDependency (
}
}
if (!pkg.name) { // TODO: don't fail on optional dependencies
throw new PnpmError('MISSING_PACKAGE_NAME', `Can't install ${wantedDependency.pref}: Missing package name`)
throw new PnpmError('MISSING_PACKAGE_NAME', `Can't install ${wantedDependency.bareSpecifier}: Missing package name`)
}
let pkgIdWithPatchHash = (pkgResponse.body.id.startsWith(`${pkg.name}@`) ? pkgResponse.body.id : `${pkg.name}@${pkgResponse.body.id}`) as PkgIdWithPatchHash
const patch = getPatchInfo(ctx.patchedDependencies, pkg.name, pkg.version)
@@ -1571,7 +1571,7 @@ async function resolveDependency (
resolvedVia: pkgResponse.body.resolvedVia,
isNew,
nodeId,
specifier: pkgResponse.body.specifier,
normalizedBareSpecifier: pkgResponse.body.normalizedBareSpecifier,
missingPeersOfChildren,
pkgId: pkgResponse.body.id,
rootDir,
@@ -1593,7 +1593,7 @@ function getManifestFromResponse (
): PackageManifest {
if (pkgResponse.body.manifest) return pkgResponse.body.manifest
return {
name: wantedDependency.pref.split('/').pop()!,
name: wantedDependency.bareSpecifier.split('/').pop()!,
version: '0.0.0',
}
}
@@ -1691,7 +1691,7 @@ function peerDependenciesWithoutOwn (pkg: PackageManifest): PeerDependencies {
return result
}
function getCatalogReplacementPref (
function getCatalogReplacementBareSpecifier (
catalogLookup: CatalogResolution,
wantedLockfile: LockfileObject,
wantedDependency: WantedDependency
@@ -1703,9 +1703,9 @@ function getCatalogReplacementPref (
const existingCatalogResolution = wantedLockfile.catalogs
?.[catalogLookup.catalogName]
?.[wantedDependency.alias]
const replacementPref = existingCatalogResolution?.specifier === catalogLookup.specifier
? replaceVersionInPref(catalogLookup.specifier, existingCatalogResolution.version)
const replacementBareSpecifier = existingCatalogResolution?.specifier === catalogLookup.specifier
? replaceVersionInBareSpecifier(catalogLookup.specifier, existingCatalogResolution.version)
: catalogLookup.specifier
return replacementPref
return replacementBareSpecifier
}

View File

@@ -54,7 +54,7 @@ export interface ResolvedDirectDependency {
version: string
name: string
catalogLookup?: CatalogLookupMetadata
specifier?: string
normalizedBareSpecifier?: string
}
/**
@@ -66,7 +66,7 @@ export interface CatalogLookupMetadata {
readonly specifier: string
/**
* The catalog protocol pref the user wrote in package.json files or as a
* The catalog protocol bareSpecifier the user wrote in package.json files or as a
* parameter to pnpm add. Ex: pnpm add foo@catalog:
*
* This will usually be 'catalog:<name>', but can simply be 'catalog:' if
@@ -74,7 +74,7 @@ export interface CatalogLookupMetadata {
* catalogName field, which would be 'default' regardless of whether users
* originally requested 'catalog:' or 'catalog:default'.
*/
readonly userSpecifiedPref: string
readonly userSpecifiedBareSpecifier: string
}
export interface Importer<WantedDepExtraProps> {
@@ -266,7 +266,7 @@ export async function resolveDependencyTree<T> (
pkgId: resolvedPackage.id,
resolution: resolvedPackage.resolution,
version: resolvedPackage.version,
specifier: dep.specifier,
normalizedBareSpecifier: dep.normalizedBareSpecifier,
}
}),
directNodeIdsByAlias: new Map(directNonLinkedDeps.map(({ alias, nodeId }) => [alias, nodeId])),
@@ -341,12 +341,12 @@ function buildTree (
function dedupeSameAliasDirectDeps (directDeps: Array<PkgAddress | LinkedDependency>, wantedDependencies: Array<WantedDependency & { isNew?: boolean }>): Array<PkgAddress | LinkedDependency> {
const deps = new Map<string, PkgAddress | LinkedDependency>()
for (const directDep of directDeps) {
const { alias, specifier } = directDep
const { alias, normalizedBareSpecifier } = directDep
if (!deps.has(alias)) {
deps.set(alias, directDep)
} else {
const wantedDep = wantedDependencies.find(dep =>
dep.alias ? dep.alias === alias : dep.pref === specifier
dep.alias ? dep.alias === alias : dep.bareSpecifier === normalizedBareSpecifier
)
if (wantedDep?.isNew) {
deps.set(alias, directDep)

View File

@@ -65,7 +65,7 @@ export async function toResolveImporter (
...dep,
updateDepth: project.updateMatching != null
? defaultUpdateDepth
: (prefIsLocalTarball(dep.pref) ? 0 : defaultUpdateDepth),
: (prefIsLocalTarball(dep.bareSpecifier) ? 0 : defaultUpdateDepth),
})
wantedDependencies = [
...project.wantedDependencies.map(
@@ -87,8 +87,8 @@ export async function toResolveImporter (
}
}
function prefIsLocalTarball (pref: string): boolean {
return pref.startsWith('file:') && pref.endsWith('.tgz')
function prefIsLocalTarball (bareSpecifier: string): boolean {
return bareSpecifier.startsWith('file:') && bareSpecifier.endsWith('.tgz')
}
async function partitionLinkedPackages (
@@ -107,7 +107,7 @@ async function partitionLinkedPackages (
if (
!dependency.alias ||
opts.workspacePackages?.get(dependency.alias) != null ||
dependency.pref.startsWith('workspace:')
dependency.bareSpecifier.startsWith('workspace:')
) {
nonLinkedDependencies.push(dependency)
return
@@ -121,7 +121,7 @@ async function partitionLinkedPackages (
nonLinkedDependencies.push(dependency)
return
}
if (!dependency.pref.startsWith('link:')) {
if (!dependency.bareSpecifier.startsWith('link:')) {
// This info-log might be better to be moved to the reporter
logger.info({
message: `${dependency.alias} is linked to ${opts.modulesDir} from ${isInnerLink}`,
@@ -144,19 +144,19 @@ type VersionSpecsByRealNames = Record<string, Record<string, 'version' | 'range'
function getVersionSpecsByRealNames (deps: Dependencies): VersionSpecsByRealNames {
const acc: VersionSpecsByRealNames = {}
for (const depName in deps) {
const currentPref = deps[depName]
if (currentPref.startsWith('npm:')) {
const pref = currentPref.slice(4)
const index = pref.lastIndexOf('@')
const spec = pref.slice(index + 1)
const currentBareSpecifier = deps[depName]
if (currentBareSpecifier.startsWith('npm:')) {
const bareSpecifier = currentBareSpecifier.slice(4)
const index = bareSpecifier.lastIndexOf('@')
const spec = bareSpecifier.slice(index + 1)
const selector = getVerSelType(spec)
if (selector != null) {
const pkgName = pref.substring(0, index)
const pkgName = bareSpecifier.substring(0, index)
acc[pkgName] = acc[pkgName] || {}
acc[pkgName][selector.normalized] = selector.type
}
} else if (!currentPref.includes(':')) { // we really care only about semver specs
const selector = getVerSelType(currentPref)
} else if (!currentBareSpecifier.includes(':')) { // we really care only about semver specs
const selector = getVerSelType(currentBareSpecifier)
if (selector != null) {
acc[depName] = acc[depName] || {}
acc[depName][selector.normalized] = selector.type

View File

@@ -25,7 +25,7 @@ export async function updateProjectManifest (
alias: rdd.alias,
nodeExecPath: wantedDep.nodeExecPath,
peer: importer.peer,
pref: rdd.catalogLookup?.userSpecifiedPref ?? rdd.specifier ?? wantedDep.pref,
bareSpecifier: rdd.catalogLookup?.userSpecifiedBareSpecifier ?? rdd.normalizedBareSpecifier ?? wantedDep.bareSpecifier,
saveType: importer.targetDependenciesField,
}
})

View File

@@ -1,4 +1,4 @@
import { parsePref, type RegistryPackageSpec } from '@pnpm/npm-resolver'
import { parseBareSpecifier, type RegistryPackageSpec } from '@pnpm/npm-resolver'
import { type WorkspacePackagesByVersion, type WorkspacePackages } from '@pnpm/resolver-base'
import semver from 'semver'
import { type WantedDependency } from './getNonDevWantedDependencies'
@@ -11,7 +11,7 @@ export function wantedDepIsLocallyAvailable (
registry: string
}
): boolean {
const spec = parsePref(wantedDependency.pref, wantedDependency.alias, opts.defaultTag || 'latest', opts.registry)
const spec = parseBareSpecifier(wantedDependency.bareSpecifier, wantedDependency.alias, opts.defaultTag || 'latest', opts.registry)
if ((spec == null) || !workspacePackages.has(spec.name)) return false
return pickMatchingLocalVersionOrNull(workspacePackages.get(spec.name)!, spec) !== null
}

View File

@@ -1,9 +1,9 @@
import { replaceVersionInPref } from '../lib/replaceVersionInPref'
import { replaceVersionInBareSpecifier } from '../lib/replaceVersionInBareSpecifier'
test('replaceVersionInPref()', () => {
expect(replaceVersionInPref('^1.0.0', '1.1.0')).toBe('1.1.0')
expect(replaceVersionInPref('npm:foo@^1.0.0', '1.1.0')).toBe('npm:foo@1.1.0')
expect(replaceVersionInPref('npm:@foo/bar@^1.0.0', '1.1.0')).toBe('npm:@foo/bar@1.1.0')
expect(replaceVersionInPref('npm:foo', '1.1.0')).toBe('npm:foo@1.1.0')
expect(replaceVersionInPref('npm:@foo/bar', '1.1.0')).toBe('npm:@foo/bar@1.1.0')
test('replaceVersionInBareSpecifier()', () => {
expect(replaceVersionInBareSpecifier('^1.0.0', '1.1.0')).toBe('1.1.0')
expect(replaceVersionInBareSpecifier('npm:foo@^1.0.0', '1.1.0')).toBe('npm:foo@1.1.0')
expect(replaceVersionInBareSpecifier('npm:@foo/bar@^1.0.0', '1.1.0')).toBe('npm:@foo/bar@1.1.0')
expect(replaceVersionInBareSpecifier('npm:foo', '1.1.0')).toBe('npm:foo@1.1.0')
expect(replaceVersionInBareSpecifier('npm:@foo/bar', '1.1.0')).toBe('npm:@foo/bar@1.1.0')
})

View File

@@ -75,12 +75,12 @@ export type PublishDependencyConverter = (
function combineConverters (...converters: readonly PublishDependencyConverter[]): PublishDependencyConverter {
return async (depName, depSpec, dir, modulesDir) => {
let pref = depSpec
let bareSpecifier = depSpec
for (const converter of converters) {
// eslint-disable-next-line no-await-in-loop
pref = await converter(depName, pref, dir, modulesDir)
bareSpecifier = await converter(depName, bareSpecifier, dir, modulesDir)
}
return pref
return bareSpecifier
}
}
@@ -114,12 +114,12 @@ async function readAndCheckManifest (depName: string, dependencyDir: string): Pr
return manifest
}
function resolveCatalogProtocol (catalogResolver: CatalogResolver, alias: string, pref: string): string {
const result = catalogResolver({ alias, pref })
function resolveCatalogProtocol (catalogResolver: CatalogResolver, alias: string, bareSpecifier: string): string {
const result = catalogResolver({ alias, bareSpecifier })
switch (result.type) {
case 'found': return result.resolution.specifier
case 'unused': return pref
case 'unused': return bareSpecifier
case 'misconfiguration': throw result.error
}
}

View File

@@ -11,7 +11,7 @@ export interface PackageSpecObject {
alias: string
nodeExecPath?: string
peer?: boolean
pref?: string
bareSpecifier?: string
saveType?: DependenciesField
}
@@ -22,7 +22,7 @@ export async function updateProjectManifestObject (
): Promise<ProjectManifest> {
for (const packageSpec of packageSpecs) {
if (packageSpec.saveType) {
const spec = packageSpec.pref ?? findSpec(packageSpec.alias, packageManifest)
const spec = packageSpec.bareSpecifier ?? findSpec(packageSpec.alias, packageManifest)
if (spec) {
packageManifest[packageSpec.saveType] = packageManifest[packageSpec.saveType] ?? {}
packageManifest[packageSpec.saveType]![packageSpec.alias] = spec
@@ -36,11 +36,11 @@ export async function updateProjectManifestObject (
packageManifest.peerDependencies[packageSpec.alias] = spec
}
}
} else if (packageSpec.pref) {
} else if (packageSpec.bareSpecifier) {
const usedDepType = guessDependencyType(packageSpec.alias, packageManifest) ?? 'dependencies'
if (usedDepType !== 'peerDependencies') {
packageManifest[usedDepType] = packageManifest[usedDepType] ?? {}
packageManifest[usedDepType]![packageSpec.alias] = packageSpec.pref
packageManifest[usedDepType]![packageSpec.alias] = packageSpec.bareSpecifier
}
}
if (packageSpec.nodeExecPath) {

View File

@@ -31,7 +31,7 @@ export async function checkForUpdates (config: Config): Promise<void> {
retries: 0,
},
})
const resolution = await resolve({ alias: packageManager.name, pref: 'latest' }, {
const resolution = await resolve({ alias: packageManager.name, bareSpecifier: 'latest' }, {
lockfileDir: config.lockfileDir ?? config.dir,
preferredVersions: {},
projectDir: config.dir,

View File

@@ -154,7 +154,7 @@ async function isAlreadyPublished (
pkgVersion: string
): Promise<boolean> {
try {
await opts.resolve({ alias: pkgName, pref: pkgVersion }, {
await opts.resolve({ alias: pkgName, bareSpecifier: pkgVersion }, {
lockfileDir: opts.lockfileDir,
preferredVersions: {},
projectDir: opts.dir,

View File

@@ -30,15 +30,15 @@ export function createResolver (
resolve: async (wantedDependency, opts) => {
const resolution = await resolveFromNpm(wantedDependency, opts as ResolveFromNpmOptions) ??
await resolveFromJsr(wantedDependency, opts as ResolveFromNpmOptions) ??
(wantedDependency.pref && (
await resolveFromTarball(fetchFromRegistry, wantedDependency as { pref: string }) ??
await resolveFromGit(wantedDependency as { pref: string }) ??
await resolveFromLocal(wantedDependency as { pref: string }, opts)
(wantedDependency.bareSpecifier && (
await resolveFromTarball(fetchFromRegistry, wantedDependency as { bareSpecifier: string }) ??
await resolveFromGit(wantedDependency as { bareSpecifier: string }) ??
await resolveFromLocal(wantedDependency as { bareSpecifier: string }, opts)
))
if (!resolution) {
throw new PnpmError(
'SPEC_NOT_SUPPORTED_BY_ANY_RESOLVER',
`${wantedDependency.alias ? wantedDependency.alias + '@' : ''}${wantedDependency.pref ?? ''} isn't supported by any available resolver.`)
`${wantedDependency.alias ? wantedDependency.alias + '@' : ''}${wantedDependency.bareSpecifier ?? ''} isn't supported by any available resolver.`)
}
return resolution
},

View File

@@ -22,12 +22,12 @@ const createResolveFromNpm = require('@pnpm/git-resolver').default
const resolveFromNpm = createResolveFromNpm({})
resolveFromNpm({
pref: 'kevva/is-negative#16fd36fe96106175d02d066171c44e2ff83bc055'
bareSpecifier: 'kevva/is-negative#16fd36fe96106175d02d066171c44e2ff83bc055'
})
.then(resolveResult => console.log(JSON.stringify(resolveResult, null, 2)))
//> {
// "id": "github.com/kevva/is-negative/16fd36fe96106175d02d066171c44e2ff83bc055",
// "normalizedPref": "github:kevva/is-negative#16fd36fe96106175d02d066171c44e2ff83bc055",
// "normalizedBareSpecifier": "github:kevva/is-negative#16fd36fe96106175d02d066171c44e2ff83bc055",
// "resolution": {
// "tarball": "https://codeload.github.com/kevva/is-negative/tar.gz/16fd36fe96106175d02d066171c44e2ff83bc055"
// },

View File

@@ -4,6 +4,6 @@ const createResolveFromNpm = require('@pnpm/git-resolver').default
const resolveFromNpm = createResolveFromNpm({})
resolveFromNpm({
pref: 'kevva/is-negative#16fd36fe96106175d02d066171c44e2ff83bc055'
bareSpecifier: 'kevva/is-negative#16fd36fe96106175d02d066171c44e2ff83bc055'
})
.then(resolveResult => console.log(JSON.stringify(resolveResult, null, 2)))

View File

@@ -1,7 +1,7 @@
import { type TarballResolution, type GitResolution, type ResolveResult, type PkgResolutionId } from '@pnpm/resolver-base'
import git from 'graceful-git'
import semver from 'semver'
import { parsePref, type HostedPackageSpec } from './parsePref'
import { parseBareSpecifier, type HostedPackageSpec } from './parseBareSpecifier'
import { createGitHostedPkgId } from './createGitHostedPkgId'
import { type AgentOptions } from '@pnpm/network.agent'
@@ -10,21 +10,21 @@ export { createGitHostedPkgId }
export type { HostedPackageSpec }
export type GitResolver = (wantedDependency: {
pref: string
bareSpecifier: string
}) => Promise<ResolveResult | null>
export function createGitResolver (
opts: AgentOptions
): GitResolver {
return async function resolveGit (wantedDependency): Promise<ResolveResult | null> {
const parsedSpec = await parsePref(wantedDependency.pref, opts)
const parsedSpec = await parseBareSpecifier(wantedDependency.bareSpecifier, opts)
if (parsedSpec == null) return null
const pref = parsedSpec.gitCommittish == null || parsedSpec.gitCommittish === ''
const bareSpecifier = parsedSpec.gitCommittish == null || parsedSpec.gitCommittish === ''
? 'HEAD'
: parsedSpec.gitCommittish
const commit = await resolveRef(parsedSpec.fetchSpec, pref, parsedSpec.gitRange)
const commit = await resolveRef(parsedSpec.fetchSpec, bareSpecifier, parsedSpec.gitRange)
let resolution
if ((parsedSpec.hosted != null) && !isSsh(parsedSpec.fetchSpec)) {
@@ -63,7 +63,7 @@ export function createGitResolver (
return {
id,
specifier: parsedSpec.normalizedPref,
normalizedBareSpecifier: parsedSpec.normalizedBareSpecifier,
resolution,
resolvedVia: 'git-repository',
}

View File

@@ -15,7 +15,7 @@ export interface HostedPackageSpec {
committish: string
tarball: () => string | undefined
}
normalizedPref: string
normalizedBareSpecifier: string
gitCommittish: string | null
gitRange?: string
path?: string
@@ -32,23 +32,23 @@ const gitProtocols = new Set([
'ssh',
])
export async function parsePref (pref: string, opts: AgentOptions): Promise<HostedPackageSpec | null> {
const hosted = HostedGit.fromUrl(pref)
export async function parseBareSpecifier (bareSpecifier: string, opts: AgentOptions): Promise<HostedPackageSpec | null> {
const hosted = HostedGit.fromUrl(bareSpecifier)
if (hosted != null) {
return fromHostedGit(hosted, opts)
}
const colonsPos = pref.indexOf(':')
const colonsPos = bareSpecifier.indexOf(':')
if (colonsPos === -1) return null
const protocol = pref.slice(0, colonsPos)
const protocol = bareSpecifier.slice(0, colonsPos)
if (protocol && gitProtocols.has(protocol.toLocaleLowerCase())) {
const correctPref = correctUrl(pref)
const url = new URL(correctPref)
const correctBareSpecifier = correctUrl(bareSpecifier)
const url = new URL(correctBareSpecifier)
if (!url?.protocol) return null
const hash = (url.hash?.length > 1) ? decodeURIComponent(url.hash.slice(1)) : null
return {
fetchSpec: urlToFetchSpec(url),
normalizedPref: pref,
normalizedBareSpecifier: bareSpecifier,
...parseGitParams(hash),
}
}
@@ -88,7 +88,7 @@ async function fromHostedGit (hosted: any, agentOptions: AgentOptions): Promise<
_fill: hosted._fill,
tarball: undefined,
},
normalizedPref: `git+${httpsUrl}`,
normalizedBareSpecifier: `git+${httpsUrl}`,
...parseGitParams(hosted.committish),
}
} else {
@@ -122,7 +122,7 @@ async function fromHostedGit (hosted: any, agentOptions: AgentOptions): Promise<
_fill: hosted._fill,
tarball: hosted.tarball,
},
normalizedPref: hosted.shortcut(),
normalizedBareSpecifier: hosted.shortcut(),
...parseGitParams(hosted.committish),
}
}

View File

@@ -16,10 +16,10 @@ function mockFetchAsPrivate (): void {
}
test('resolveFromGit() with commit', async () => {
const resolveResult = await resolveFromGit({ pref: 'zkochan/is-negative#163360a8d3ae6bee9524541043197ff356f8ed99' })
const resolveResult = await resolveFromGit({ bareSpecifier: 'zkochan/is-negative#163360a8d3ae6bee9524541043197ff356f8ed99' })
expect(resolveResult).toStrictEqual({
id: 'https://codeload.github.com/zkochan/is-negative/tar.gz/163360a8d3ae6bee9524541043197ff356f8ed99',
specifier: 'github:zkochan/is-negative#163360a8d3ae6bee9524541043197ff356f8ed99',
normalizedBareSpecifier: 'github:zkochan/is-negative#163360a8d3ae6bee9524541043197ff356f8ed99',
resolution: {
tarball: 'https://codeload.github.com/zkochan/is-negative/tar.gz/163360a8d3ae6bee9524541043197ff356f8ed99',
},
@@ -33,10 +33,10 @@ test('resolveFromGit() with no commit', async () => {
// The issue occurred because .hosted field (which is class from the 'hosted-git-info' package)
// was mutated. A 'committish' field was added to it.
for (let i = 0; i < 2; i++) {
const resolveResult = await resolveFromGit({ pref: 'zkochan/is-negative' }) // eslint-disable-line no-await-in-loop
const resolveResult = await resolveFromGit({ bareSpecifier: 'zkochan/is-negative' }) // eslint-disable-line no-await-in-loop
expect(resolveResult).toStrictEqual({
id: 'https://codeload.github.com/zkochan/is-negative/tar.gz/1d7e288222b53a0cab90a331f1865220ec29560c',
specifier: 'github:zkochan/is-negative',
normalizedBareSpecifier: 'github:zkochan/is-negative',
resolution: {
tarball: 'https://codeload.github.com/zkochan/is-negative/tar.gz/1d7e288222b53a0cab90a331f1865220ec29560c',
},
@@ -46,10 +46,10 @@ test('resolveFromGit() with no commit', async () => {
})
test('resolveFromGit() with no commit, when main branch is not master', async () => {
const resolveResult = await resolveFromGit({ pref: 'zoli-forks/cmd-shim' })
const resolveResult = await resolveFromGit({ bareSpecifier: 'zoli-forks/cmd-shim' })
expect(resolveResult).toStrictEqual({
id: 'https://codeload.github.com/zoli-forks/cmd-shim/tar.gz/a00a83a1593edb6e395d3ce41f2ef70edf7e2cf5',
specifier: 'github:zoli-forks/cmd-shim',
normalizedBareSpecifier: 'github:zoli-forks/cmd-shim',
resolution: {
tarball: 'https://codeload.github.com/zoli-forks/cmd-shim/tar.gz/a00a83a1593edb6e395d3ce41f2ef70edf7e2cf5',
},
@@ -58,10 +58,10 @@ test('resolveFromGit() with no commit, when main branch is not master', async ()
})
test('resolveFromGit() with partial commit', async () => {
const resolveResult = await resolveFromGit({ pref: 'zoli-forks/cmd-shim#a00a83a' })
const resolveResult = await resolveFromGit({ bareSpecifier: 'zoli-forks/cmd-shim#a00a83a' })
expect(resolveResult).toStrictEqual({
id: 'https://codeload.github.com/zoli-forks/cmd-shim/tar.gz/a00a83a',
specifier: 'github:zoli-forks/cmd-shim#a00a83a',
normalizedBareSpecifier: 'github:zoli-forks/cmd-shim#a00a83a',
resolution: {
tarball: 'https://codeload.github.com/zoli-forks/cmd-shim/tar.gz/a00a83a',
},
@@ -70,10 +70,10 @@ test('resolveFromGit() with partial commit', async () => {
})
test('resolveFromGit() with branch', async () => {
const resolveResult = await resolveFromGit({ pref: 'zkochan/is-negative#canary' })
const resolveResult = await resolveFromGit({ bareSpecifier: 'zkochan/is-negative#canary' })
expect(resolveResult).toStrictEqual({
id: 'https://codeload.github.com/zkochan/is-negative/tar.gz/4c39fbc124cd4944ee51cb082ad49320fab58121',
specifier: 'github:zkochan/is-negative#canary',
normalizedBareSpecifier: 'github:zkochan/is-negative#canary',
resolution: {
tarball: 'https://codeload.github.com/zkochan/is-negative/tar.gz/4c39fbc124cd4944ee51cb082ad49320fab58121',
},
@@ -82,10 +82,10 @@ test('resolveFromGit() with branch', async () => {
})
test('resolveFromGit() with branch relative to refs', async () => {
const resolveResult = await resolveFromGit({ pref: 'zkochan/is-negative#heads/canary' })
const resolveResult = await resolveFromGit({ bareSpecifier: 'zkochan/is-negative#heads/canary' })
expect(resolveResult).toStrictEqual({
id: 'https://codeload.github.com/zkochan/is-negative/tar.gz/4c39fbc124cd4944ee51cb082ad49320fab58121',
specifier: 'github:zkochan/is-negative#heads/canary',
normalizedBareSpecifier: 'github:zkochan/is-negative#heads/canary',
resolution: {
tarball: 'https://codeload.github.com/zkochan/is-negative/tar.gz/4c39fbc124cd4944ee51cb082ad49320fab58121',
},
@@ -94,10 +94,10 @@ test('resolveFromGit() with branch relative to refs', async () => {
})
test('resolveFromGit() with tag', async () => {
const resolveResult = await resolveFromGit({ pref: 'zkochan/is-negative#2.0.1' })
const resolveResult = await resolveFromGit({ bareSpecifier: 'zkochan/is-negative#2.0.1' })
expect(resolveResult).toStrictEqual({
id: 'https://codeload.github.com/zkochan/is-negative/tar.gz/2fa0531ab04e300a24ef4fd7fb3a280eccb7ccc5',
specifier: 'github:zkochan/is-negative#2.0.1',
normalizedBareSpecifier: 'github:zkochan/is-negative#2.0.1',
resolution: {
tarball: 'https://codeload.github.com/zkochan/is-negative/tar.gz/2fa0531ab04e300a24ef4fd7fb3a280eccb7ccc5',
},
@@ -106,10 +106,10 @@ test('resolveFromGit() with tag', async () => {
})
test.skip('resolveFromGit() with tag (v-prefixed tag)', async () => {
const resolveResult = await resolveFromGit({ pref: 'andreineculau/npm-publish-git#v0.0.7' })
const resolveResult = await resolveFromGit({ bareSpecifier: 'andreineculau/npm-publish-git#v0.0.7' })
expect(resolveResult).toStrictEqual({
id: 'https://codeload.github.com/andreineculau/npm-publish-git/tar.gz/a2f8d94562884e9529cb12c0818312ac87ab7f0b',
specifier: 'github:andreineculau/npm-publish-git#v0.0.7',
normalizedBareSpecifier: 'github:andreineculau/npm-publish-git#v0.0.7',
resolution: {
tarball: 'https://codeload.github.com/andreineculau/npm-publish-git/tar.gz/a2f8d94562884e9529cb12c0818312ac87ab7f0b',
},
@@ -118,10 +118,10 @@ test.skip('resolveFromGit() with tag (v-prefixed tag)', async () => {
})
test('resolveFromGit() with strict semver', async () => {
const resolveResult = await resolveFromGit({ pref: 'zkochan/is-negative#semver:1.0.0' })
const resolveResult = await resolveFromGit({ bareSpecifier: 'zkochan/is-negative#semver:1.0.0' })
expect(resolveResult).toStrictEqual({
id: 'https://codeload.github.com/zkochan/is-negative/tar.gz/163360a8d3ae6bee9524541043197ff356f8ed99',
specifier: 'github:zkochan/is-negative#semver:1.0.0',
normalizedBareSpecifier: 'github:zkochan/is-negative#semver:1.0.0',
resolution: {
tarball: 'https://codeload.github.com/zkochan/is-negative/tar.gz/163360a8d3ae6bee9524541043197ff356f8ed99',
},
@@ -130,10 +130,10 @@ test('resolveFromGit() with strict semver', async () => {
})
test.skip('resolveFromGit() with strict semver (v-prefixed tag)', async () => {
const resolveResult = await resolveFromGit({ pref: 'andreineculau/npm-publish-git#semver:v0.0.7' })
const resolveResult = await resolveFromGit({ bareSpecifier: 'andreineculau/npm-publish-git#semver:v0.0.7' })
expect(resolveResult).toStrictEqual({
id: 'https://codeload.github.com/andreineculau/npm-publish-git/tar.gz/a2f8d94562884e9529cb12c0818312ac87ab7f0b',
specifier: 'github:andreineculau/npm-publish-git#semver:v0.0.7',
normalizedBareSpecifier: 'github:andreineculau/npm-publish-git#semver:v0.0.7',
resolution: {
tarball: 'https://codeload.github.com/andreineculau/npm-publish-git/tar.gz/a2f8d94562884e9529cb12c0818312ac87ab7f0b',
},
@@ -142,10 +142,10 @@ test.skip('resolveFromGit() with strict semver (v-prefixed tag)', async () => {
})
test('resolveFromGit() with range semver', async () => {
const resolveResult = await resolveFromGit({ pref: 'zkochan/is-negative#semver:^1.0.0' })
const resolveResult = await resolveFromGit({ bareSpecifier: 'zkochan/is-negative#semver:^1.0.0' })
expect(resolveResult).toStrictEqual({
id: 'https://codeload.github.com/zkochan/is-negative/tar.gz/9a89df745b2ec20ae7445d3d9853ceaeef5b0b72',
specifier: 'github:zkochan/is-negative#semver:^1.0.0',
normalizedBareSpecifier: 'github:zkochan/is-negative#semver:^1.0.0',
resolution: {
tarball: 'https://codeload.github.com/zkochan/is-negative/tar.gz/9a89df745b2ec20ae7445d3d9853ceaeef5b0b72',
},
@@ -154,10 +154,10 @@ test('resolveFromGit() with range semver', async () => {
})
test.skip('resolveFromGit() with range semver (v-prefixed tag)', async () => {
const resolveResult = await resolveFromGit({ pref: 'andreineculau/npm-publish-git#semver:<=v0.0.7' })
const resolveResult = await resolveFromGit({ bareSpecifier: 'andreineculau/npm-publish-git#semver:<=v0.0.7' })
expect(resolveResult).toStrictEqual({
id: 'https://codeload.github.com/andreineculau/npm-publish-git/tar.gz/a2f8d94562884e9529cb12c0818312ac87ab7f0b',
specifier: 'github:andreineculau/npm-publish-git#semver:<=v0.0.7',
normalizedBareSpecifier: 'github:andreineculau/npm-publish-git#semver:<=v0.0.7',
resolution: {
tarball: 'https://codeload.github.com/andreineculau/npm-publish-git/tar.gz/a2f8d94562884e9529cb12c0818312ac87ab7f0b',
},
@@ -166,10 +166,10 @@ test.skip('resolveFromGit() with range semver (v-prefixed tag)', async () => {
})
test('resolveFromGit() with sub folder', async () => {
const resolveResult = await resolveFromGit({ pref: 'github:RexSkz/test-git-subfolder-fetch.git#path:/packages/simple-react-app' })
const resolveResult = await resolveFromGit({ bareSpecifier: 'github:RexSkz/test-git-subfolder-fetch.git#path:/packages/simple-react-app' })
expect(resolveResult).toStrictEqual({
id: 'https://codeload.github.com/RexSkz/test-git-subfolder-fetch/tar.gz/2b42a57a945f19f8ffab8ecbd2021fdc2c58ee22#path:/packages/simple-react-app',
specifier: 'github:RexSkz/test-git-subfolder-fetch#path:/packages/simple-react-app',
normalizedBareSpecifier: 'github:RexSkz/test-git-subfolder-fetch#path:/packages/simple-react-app',
resolution: {
tarball: 'https://codeload.github.com/RexSkz/test-git-subfolder-fetch/tar.gz/2b42a57a945f19f8ffab8ecbd2021fdc2c58ee22',
path: '/packages/simple-react-app',
@@ -179,10 +179,10 @@ test('resolveFromGit() with sub folder', async () => {
})
test('resolveFromGit() with both sub folder and branch', async () => {
const resolveResult = await resolveFromGit({ pref: 'github:RexSkz/test-git-subfolder-fetch.git#beta&path:/packages/simple-react-app' })
const resolveResult = await resolveFromGit({ bareSpecifier: 'github:RexSkz/test-git-subfolder-fetch.git#beta&path:/packages/simple-react-app' })
expect(resolveResult).toStrictEqual({
id: 'https://codeload.github.com/RexSkz/test-git-subfolder-fetch/tar.gz/777e8a3e78cc89bbf41fb3fd9f6cf922d5463313#path:/packages/simple-react-app',
specifier: 'github:RexSkz/test-git-subfolder-fetch#beta&path:/packages/simple-react-app',
normalizedBareSpecifier: 'github:RexSkz/test-git-subfolder-fetch#beta&path:/packages/simple-react-app',
resolution: {
tarball: 'https://codeload.github.com/RexSkz/test-git-subfolder-fetch/tar.gz/777e8a3e78cc89bbf41fb3fd9f6cf922d5463313',
path: '/packages/simple-react-app',
@@ -193,13 +193,13 @@ test('resolveFromGit() with both sub folder and branch', async () => {
test('resolveFromGit() fails when ref not found', async () => {
await expect(
resolveFromGit({ pref: 'zkochan/is-negative#bad-ref' })
resolveFromGit({ bareSpecifier: 'zkochan/is-negative#bad-ref' })
).rejects.toThrow(/Could not resolve bad-ref to a commit of (https|git):\/\/github.com\/zkochan\/is-negative.git./)
})
test('resolveFromGit() fails when semver ref not found', async () => {
await expect(
resolveFromGit({ pref: 'zkochan/is-negative#semver:^100.0.0' })
resolveFromGit({ bareSpecifier: 'zkochan/is-negative#semver:^100.0.0' })
).rejects.toThrow(/Could not resolve \^100.0.0 to a commit of (https|git):\/\/github.com\/zkochan\/is-negative.git. Available versions are: 1.0.0, 1.0.1, 2.0.0, 2.0.1, 2.0.2, 2.1.0/)
})
@@ -209,10 +209,10 @@ test('resolveFromGit() with commit from non-github repo', async () => {
return
}
const localPath = process.cwd()
const resolveResult = await resolveFromGit({ pref: `git+file://${localPath}#988c61e11dc8d9ca0b5580cb15291951812549dc` })
const resolveResult = await resolveFromGit({ bareSpecifier: `git+file://${localPath}#988c61e11dc8d9ca0b5580cb15291951812549dc` })
expect(resolveResult).toStrictEqual({
id: `git+file://${localPath}#988c61e11dc8d9ca0b5580cb15291951812549dc`,
specifier: `git+file://${localPath}#988c61e11dc8d9ca0b5580cb15291951812549dc`,
normalizedBareSpecifier: `git+file://${localPath}#988c61e11dc8d9ca0b5580cb15291951812549dc`,
resolution: {
commit: '988c61e11dc8d9ca0b5580cb15291951812549dc',
repo: `file://${localPath}`,
@@ -227,10 +227,10 @@ test.skip('resolveFromGit() with commit from non-github repo with no commit', as
const localPath = path.resolve('..', '..')
const result = await git(['rev-parse', 'origin/master'], { retries: 0 })
const hash: string = result.stdout.trim()
const resolveResult = await resolveFromGit({ pref: `git+file://${localPath}` })
const resolveResult = await resolveFromGit({ bareSpecifier: `git+file://${localPath}` })
expect(resolveResult).toStrictEqual({
id: `git+file://${localPath}#${hash}`,
specifier: `git+file://${localPath}`,
normalizedBareSpecifier: `git+file://${localPath}`,
resolution: {
commit: hash,
repo: `file://${localPath}`,
@@ -246,10 +246,10 @@ test.skip('resolveFromGit() bitbucket with commit', async () => {
if (isWindows()) {
return
}
const resolveResult = await resolveFromGit({ pref: 'bitbucket:pnpmjs/git-resolver#988c61e11dc8d9ca0b5580cb15291951812549dc' })
const resolveResult = await resolveFromGit({ bareSpecifier: 'bitbucket:pnpmjs/git-resolver#988c61e11dc8d9ca0b5580cb15291951812549dc' })
expect(resolveResult).toStrictEqual({
id: 'https://bitbucket.org/pnpmjs/git-resolver/get/988c61e11dc8d9ca0b5580cb15291951812549dc.tar.gz',
specifier: 'bitbucket:pnpmjs/git-resolver#988c61e11dc8d9ca0b5580cb15291951812549dc',
normalizedBareSpecifier: 'bitbucket:pnpmjs/git-resolver#988c61e11dc8d9ca0b5580cb15291951812549dc',
resolution: {
tarball: 'https://bitbucket.org/pnpmjs/git-resolver/get/988c61e11dc8d9ca0b5580cb15291951812549dc.tar.gz',
},
@@ -259,12 +259,12 @@ test.skip('resolveFromGit() bitbucket with commit', async () => {
// Stopped working. Environmental issue.
test.skip('resolveFromGit() bitbucket with no commit', async () => {
const resolveResult = await resolveFromGit({ pref: 'bitbucket:pnpmjs/git-resolver' })
const resolveResult = await resolveFromGit({ bareSpecifier: 'bitbucket:pnpmjs/git-resolver' })
const result = await git(['ls-remote', '--refs', 'https://bitbucket.org/pnpmjs/git-resolver.git', 'master'], { retries: 0 })
const hash: string = result.stdout.trim().split('\t')[0]
expect(resolveResult).toStrictEqual({
id: `https://bitbucket.org/pnpmjs/git-resolver/get/${hash}.tar.gz`,
specifier: 'bitbucket:pnpmjs/git-resolver',
normalizedBareSpecifier: 'bitbucket:pnpmjs/git-resolver',
resolution: {
tarball: `https://bitbucket.org/pnpmjs/git-resolver/get/${hash}.tar.gz`,
},
@@ -274,12 +274,12 @@ test.skip('resolveFromGit() bitbucket with no commit', async () => {
// Stopped working. Environmental issue.
test.skip('resolveFromGit() bitbucket with branch', async () => {
const resolveResult = await resolveFromGit({ pref: 'bitbucket:pnpmjs/git-resolver#master' })
const resolveResult = await resolveFromGit({ bareSpecifier: 'bitbucket:pnpmjs/git-resolver#master' })
const result = await git(['ls-remote', '--refs', 'https://bitbucket.org/pnpmjs/git-resolver.git', 'master'], { retries: 0 })
const hash: string = result.stdout.trim().split('\t')[0]
expect(resolveResult).toStrictEqual({
id: `https://bitbucket.org/pnpmjs/git-resolver/get/${hash}.tar.gz`,
specifier: 'bitbucket:pnpmjs/git-resolver#master',
normalizedBareSpecifier: 'bitbucket:pnpmjs/git-resolver#master',
resolution: {
tarball: `https://bitbucket.org/pnpmjs/git-resolver/get/${hash}.tar.gz`,
},
@@ -289,10 +289,10 @@ test.skip('resolveFromGit() bitbucket with branch', async () => {
// Stopped working. Environmental issue.
test.skip('resolveFromGit() bitbucket with tag', async () => {
const resolveResult = await resolveFromGit({ pref: 'bitbucket:pnpmjs/git-resolver#0.3.4' })
const resolveResult = await resolveFromGit({ bareSpecifier: 'bitbucket:pnpmjs/git-resolver#0.3.4' })
expect(resolveResult).toStrictEqual({
id: 'https://bitbucket.org/pnpmjs/git-resolver/get/87cf6a67064d2ce56e8cd20624769a5512b83ff9.tar.gz',
specifier: 'bitbucket:pnpmjs/git-resolver#0.3.4',
normalizedBareSpecifier: 'bitbucket:pnpmjs/git-resolver#0.3.4',
resolution: {
tarball: 'https://bitbucket.org/pnpmjs/git-resolver/get/87cf6a67064d2ce56e8cd20624769a5512b83ff9.tar.gz',
},
@@ -301,10 +301,10 @@ test.skip('resolveFromGit() bitbucket with tag', async () => {
})
test('resolveFromGit() gitlab with colon in the URL', async () => {
const resolveResult = await resolveFromGit({ pref: 'ssh://git@gitlab:pnpm/git-resolver#988c61e11dc8d9ca0b5580cb15291951812549dc' })
const resolveResult = await resolveFromGit({ bareSpecifier: 'ssh://git@gitlab:pnpm/git-resolver#988c61e11dc8d9ca0b5580cb15291951812549dc' })
expect(resolveResult).toStrictEqual({
id: 'git+ssh://git@gitlab/pnpm/git-resolver#988c61e11dc8d9ca0b5580cb15291951812549dc',
specifier: 'ssh://git@gitlab:pnpm/git-resolver#988c61e11dc8d9ca0b5580cb15291951812549dc',
normalizedBareSpecifier: 'ssh://git@gitlab:pnpm/git-resolver#988c61e11dc8d9ca0b5580cb15291951812549dc',
resolution: {
commit: '988c61e11dc8d9ca0b5580cb15291951812549dc',
repo: 'ssh://git@gitlab/pnpm/git-resolver',
@@ -316,10 +316,10 @@ test('resolveFromGit() gitlab with colon in the URL', async () => {
// This test stopped working. Probably an environmental issue.
test.skip('resolveFromGit() gitlab with commit', async () => {
const resolveResult = await resolveFromGit({ pref: 'gitlab:pnpm/git-resolver#988c61e11dc8d9ca0b5580cb15291951812549dc' })
const resolveResult = await resolveFromGit({ bareSpecifier: 'gitlab:pnpm/git-resolver#988c61e11dc8d9ca0b5580cb15291951812549dc' })
expect(resolveResult).toStrictEqual({
id: 'https://gitlab.com/api/v4/projects/pnpm%2Fgit-resolver/repository/archive.tar.gz?ref=988c61e11dc8d9ca0b5580cb15291951812549dc',
specifier: 'gitlab:pnpm/git-resolver#988c61e11dc8d9ca0b5580cb15291951812549dc',
normalizedBareSpecifier: 'gitlab:pnpm/git-resolver#988c61e11dc8d9ca0b5580cb15291951812549dc',
resolution: {
tarball: 'https://gitlab.com/api/v4/projects/pnpm%2Fgit-resolver/repository/archive.tar.gz?ref=988c61e11dc8d9ca0b5580cb15291951812549dc',
},
@@ -329,12 +329,12 @@ test.skip('resolveFromGit() gitlab with commit', async () => {
// This test stopped working. Probably an environmental issue.
test.skip('resolveFromGit() gitlab with no commit', async () => {
const resolveResult = await resolveFromGit({ pref: 'gitlab:pnpm/git-resolver' })
const resolveResult = await resolveFromGit({ bareSpecifier: 'gitlab:pnpm/git-resolver' })
const result = await git(['ls-remote', '--refs', 'https://gitlab.com/pnpm/git-resolver.git', 'master'], { retries: 0 })
const hash: string = result.stdout.trim().split('\t')[0]
expect(resolveResult).toStrictEqual({
id: `https://gitlab.com/api/v4/projects/pnpm%2Fgit-resolver/repository/archive.tar.gz?ref=${hash}`,
specifier: 'gitlab:pnpm/git-resolver',
normalizedBareSpecifier: 'gitlab:pnpm/git-resolver',
resolution: {
tarball: `https://gitlab.com/api/v4/projects/pnpm%2Fgit-resolver/repository/archive.tar.gz?ref=${hash}`,
},
@@ -344,12 +344,12 @@ test.skip('resolveFromGit() gitlab with no commit', async () => {
// This test stopped working. Probably an environmental issue.
test.skip('resolveFromGit() gitlab with branch', async () => {
const resolveResult = await resolveFromGit({ pref: 'gitlab:pnpm/git-resolver#master' })
const resolveResult = await resolveFromGit({ bareSpecifier: 'gitlab:pnpm/git-resolver#master' })
const result = await git(['ls-remote', '--refs', 'https://gitlab.com/pnpm/git-resolver.git', 'master'], { retries: 0 })
const hash: string = result.stdout.trim().split('\t')[0]
expect(resolveResult).toStrictEqual({
id: `https://gitlab.com/api/v4/projects/pnpm%2Fgit-resolver/repository/archive.tar.gz?ref=${hash}`,
specifier: 'gitlab:pnpm/git-resolver#master',
normalizedBareSpecifier: 'gitlab:pnpm/git-resolver#master',
resolution: {
tarball: `https://gitlab.com/api/v4/projects/pnpm%2Fgit-resolver/repository/archive.tar.gz?ref=${hash}`,
},
@@ -359,10 +359,10 @@ test.skip('resolveFromGit() gitlab with branch', async () => {
// This test stopped working. Probably an environmental issue.
test.skip('resolveFromGit() gitlab with tag', async () => {
const resolveResult = await resolveFromGit({ pref: 'gitlab:pnpm/git-resolver#0.3.4' })
const resolveResult = await resolveFromGit({ bareSpecifier: 'gitlab:pnpm/git-resolver#0.3.4' })
expect(resolveResult).toStrictEqual({
id: 'https://gitlab.com/api/v4/projects/pnpm%2Fgit-resolver/repository/archive.tar.gz?ref=87cf6a67064d2ce56e8cd20624769a5512b83ff9',
specifier: 'gitlab:pnpm/git-resolver#0.3.4',
normalizedBareSpecifier: 'gitlab:pnpm/git-resolver#0.3.4',
resolution: {
tarball: 'https://gitlab.com/api/v4/projects/pnpm%2Fgit-resolver/repository/archive.tar.gz?ref=87cf6a67064d2ce56e8cd20624769a5512b83ff9',
},
@@ -371,10 +371,10 @@ test.skip('resolveFromGit() gitlab with tag', async () => {
})
test('resolveFromGit() normalizes full url', async () => {
const resolveResult = await resolveFromGit({ pref: 'git+ssh://git@github.com:zkochan/is-negative.git#2.0.1' })
const resolveResult = await resolveFromGit({ bareSpecifier: 'git+ssh://git@github.com:zkochan/is-negative.git#2.0.1' })
expect(resolveResult).toStrictEqual({
id: 'https://codeload.github.com/zkochan/is-negative/tar.gz/2fa0531ab04e300a24ef4fd7fb3a280eccb7ccc5',
specifier: 'github:zkochan/is-negative#2.0.1',
normalizedBareSpecifier: 'github:zkochan/is-negative#2.0.1',
resolution: {
tarball: 'https://codeload.github.com/zkochan/is-negative/tar.gz/2fa0531ab04e300a24ef4fd7fb3a280eccb7ccc5',
},
@@ -383,10 +383,10 @@ test('resolveFromGit() normalizes full url', async () => {
})
test('resolveFromGit() normalizes full url with port', async () => {
const resolveResult = await resolveFromGit({ pref: 'git+ssh://git@github.com:22:zkochan/is-negative.git#2.0.1' })
const resolveResult = await resolveFromGit({ bareSpecifier: 'git+ssh://git@github.com:22:zkochan/is-negative.git#2.0.1' })
expect(resolveResult).toStrictEqual({
id: 'https://codeload.github.com/zkochan/is-negative/tar.gz/2fa0531ab04e300a24ef4fd7fb3a280eccb7ccc5',
specifier: 'github:zkochan/is-negative#2.0.1',
normalizedBareSpecifier: 'github:zkochan/is-negative#2.0.1',
resolution: {
tarball: 'https://codeload.github.com/zkochan/is-negative/tar.gz/2fa0531ab04e300a24ef4fd7fb3a280eccb7ccc5',
},
@@ -395,10 +395,10 @@ test('resolveFromGit() normalizes full url with port', async () => {
})
test('resolveFromGit() normalizes full url (alternative form)', async () => {
const resolveResult = await resolveFromGit({ pref: 'git+ssh://git@github.com/zkochan/is-negative.git#2.0.1' })
const resolveResult = await resolveFromGit({ bareSpecifier: 'git+ssh://git@github.com/zkochan/is-negative.git#2.0.1' })
expect(resolveResult).toStrictEqual({
id: 'https://codeload.github.com/zkochan/is-negative/tar.gz/2fa0531ab04e300a24ef4fd7fb3a280eccb7ccc5',
specifier: 'github:zkochan/is-negative#2.0.1',
normalizedBareSpecifier: 'github:zkochan/is-negative#2.0.1',
resolution: {
tarball: 'https://codeload.github.com/zkochan/is-negative/tar.gz/2fa0531ab04e300a24ef4fd7fb3a280eccb7ccc5',
},
@@ -407,10 +407,10 @@ test('resolveFromGit() normalizes full url (alternative form)', async () => {
})
test('resolveFromGit() normalizes full url (alternative form 2)', async () => {
const resolveResult = await resolveFromGit({ pref: 'https://github.com/zkochan/is-negative.git#2.0.1' })
const resolveResult = await resolveFromGit({ bareSpecifier: 'https://github.com/zkochan/is-negative.git#2.0.1' })
expect(resolveResult).toStrictEqual({
id: 'https://codeload.github.com/zkochan/is-negative/tar.gz/2fa0531ab04e300a24ef4fd7fb3a280eccb7ccc5',
specifier: 'github:zkochan/is-negative#2.0.1',
normalizedBareSpecifier: 'github:zkochan/is-negative#2.0.1',
resolution: {
tarball: 'https://codeload.github.com/zkochan/is-negative/tar.gz/2fa0531ab04e300a24ef4fd7fb3a280eccb7ccc5',
},
@@ -419,13 +419,13 @@ test('resolveFromGit() normalizes full url (alternative form 2)', async () => {
})
// This test relies on implementation detail.
// current implementation does not try git ls-remote --refs on pref with full commit hash, this fake repo url will pass.
// current implementation does not try git ls-remote --refs on bareSpecifier with full commit hash, this fake repo url will pass.
test('resolveFromGit() private repo with commit hash', async () => {
mockFetchAsPrivate()
const resolveResult = await resolveFromGit({ pref: 'fake/private-repo#2fa0531ab04e300a24ef4fd7fb3a280eccb7ccc5' })
const resolveResult = await resolveFromGit({ bareSpecifier: 'fake/private-repo#2fa0531ab04e300a24ef4fd7fb3a280eccb7ccc5' })
expect(resolveResult).toStrictEqual({
id: 'git+ssh://git@github.com/fake/private-repo.git#2fa0531ab04e300a24ef4fd7fb3a280eccb7ccc5',
specifier: 'github:fake/private-repo#2fa0531ab04e300a24ef4fd7fb3a280eccb7ccc5',
normalizedBareSpecifier: 'github:fake/private-repo#2fa0531ab04e300a24ef4fd7fb3a280eccb7ccc5',
resolution: {
commit: '2fa0531ab04e300a24ef4fd7fb3a280eccb7ccc5',
repo: 'git+ssh://git@github.com/fake/private-repo.git',
@@ -448,10 +448,10 @@ test('resolve a private repository using the HTTPS protocol without auth token',
}
})
mockFetchAsPrivate()
const resolveResult = await resolveFromGit({ pref: 'git+https://github.com/foo/bar.git' })
const resolveResult = await resolveFromGit({ bareSpecifier: 'git+https://github.com/foo/bar.git' })
expect(resolveResult).toStrictEqual({
id: 'git+ssh://git@github.com/foo/bar.git#0000000000000000000000000000000000000000',
specifier: 'github:foo/bar',
normalizedBareSpecifier: 'github:foo/bar',
resolution: {
commit: '0000000000000000000000000000000000000000',
repo: 'git+ssh://git@github.com/foo/bar.git',
@@ -470,10 +470,10 @@ test('resolve a private repository using the HTTPS protocol with a commit hash',
stdout: 'aabbccddeeff\tHEAD',
}
})
const resolveResult = await resolveFromGit({ pref: 'git+https://github.com/foo/bar.git#aabbccddeeff' })
const resolveResult = await resolveFromGit({ bareSpecifier: 'git+https://github.com/foo/bar.git#aabbccddeeff' })
expect(resolveResult).toStrictEqual({
id: 'git+https://github.com/foo/bar.git#aabbccddeeff',
specifier: 'git+https://github.com/foo/bar.git',
normalizedBareSpecifier: 'git+https://github.com/foo/bar.git',
resolution: {
// cspell:ignore aabbccddeeff
commit: 'aabbccddeeff',
@@ -497,10 +497,10 @@ aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\trefs/heads/master\
return { stdout: '0000000000000000000000000000000000000000\tHEAD' }
})
mockFetchAsPrivate()
const resolveResult = await resolveFromGit({ pref: 'git+https://0000000000000000000000000000000000000000:x-oauth-basic@github.com/foo/bar.git' })
const resolveResult = await resolveFromGit({ bareSpecifier: 'git+https://0000000000000000000000000000000000000000:x-oauth-basic@github.com/foo/bar.git' })
expect(resolveResult).toStrictEqual({
id: 'git+https://0000000000000000000000000000000000000000:x-oauth-basic@github.com/foo/bar.git#0000000000000000000000000000000000000000',
specifier: 'git+https://0000000000000000000000000000000000000000:x-oauth-basic@github.com/foo/bar.git',
normalizedBareSpecifier: 'git+https://0000000000000000000000000000000000000000:x-oauth-basic@github.com/foo/bar.git',
resolution: {
commit: '0000000000000000000000000000000000000000',
repo: 'https://0000000000000000000000000000000000000000:x-oauth-basic@github.com/foo/bar.git',
@@ -527,10 +527,10 @@ ed3de20970d980cf21a07fd8b8732c70d5182303\trefs/tags/v0.0.38\n\
cba04669e621b85fbdb33371604de1a2898e68e9\trefs/tags/v0.0.39',
}
})
const resolveResult = await resolveFromGit({ pref: 'git+ssh://git@example.com/org/repo.git#semver:~0.0.38' })
const resolveResult = await resolveFromGit({ bareSpecifier: 'git+ssh://git@example.com/org/repo.git#semver:~0.0.38' })
expect(resolveResult).toStrictEqual({
id: 'git+ssh://git@example.com/org/repo.git#cba04669e621b85fbdb33371604de1a2898e68e9',
specifier: 'git+ssh://git@example.com/org/repo.git#semver:~0.0.38',
normalizedBareSpecifier: 'git+ssh://git@example.com/org/repo.git#semver:~0.0.38',
resolution: {
commit: 'cba04669e621b85fbdb33371604de1a2898e68e9',
repo: 'ssh://git@example.com/org/repo.git',
@@ -557,10 +557,10 @@ ed3de20970d980cf21a07fd8b8732c70d5182303\trefs/tags/v0.0.38\n\
cba04669e621b85fbdb33371604de1a2898e68e9\trefs/tags/v0.0.39',
}
})
const resolveResult = await resolveFromGit({ pref: 'git+ssh://git@example.com:org/repo.git#semver:~0.0.38' })
const resolveResult = await resolveFromGit({ bareSpecifier: 'git+ssh://git@example.com:org/repo.git#semver:~0.0.38' })
expect(resolveResult).toStrictEqual({
id: 'git+ssh://git@example.com/org/repo.git#cba04669e621b85fbdb33371604de1a2898e68e9',
specifier: 'git+ssh://git@example.com:org/repo.git#semver:~0.0.38',
normalizedBareSpecifier: 'git+ssh://git@example.com:org/repo.git#semver:~0.0.38',
resolution: {
commit: 'cba04669e621b85fbdb33371604de1a2898e68e9',
repo: 'ssh://git@example.com/org/repo.git',

View File

@@ -1,4 +1,4 @@
import { parsePref } from '../lib/parsePref'
import { parseBareSpecifier } from '../lib/parseBareSpecifier'
test.each([
['ssh://username:password@example.com:repo.git', 'ssh://username:password@example.com/repo.git'],
@@ -13,7 +13,7 @@ test.each([
['git+ssh://username:password@example.com:22/repo/@foo.git#path:/a/@b', 'ssh://username:password@example.com:22/repo/@foo.git'],
['git+ssh://username:password@example.com:22/repo/@foo.git#path:/a/@b&dev', 'ssh://username:password@example.com:22/repo/@foo.git'],
])('the right colon is escaped in %s', async (input, output) => {
const parsed = await parsePref(input, {})
const parsed = await parseBareSpecifier(input, {})
expect(parsed?.fetchSpec).toBe(output)
})
@@ -41,13 +41,13 @@ test.each([
['git+ssh://username:password@example.com:22/repo/@foo.git', undefined],
['git+ssh://username:password@example.com:22/repo/@foo.git#dev', undefined],
])('the path of %s should be %s', async (input, output) => {
const parsed = await parsePref(input, {})
const parsed = await parseBareSpecifier(input, {})
expect(parsed?.path).toBe(output)
})
test.each([
['git+https://github.com/pnpm/pnpm.git', 'https://github.com/pnpm/pnpm.git'],
])('the fetchSpec of %s should be %s', async (input, output) => {
const parsed = await parsePref(input, {})
const parsed = await parseBareSpecifier(input, {})
expect(parsed?.fetchSpec).toBe(output)
})

View File

@@ -18,10 +18,10 @@ pnpm add @pnpm/local-resolver
'use strict'
const resolveFromLocal = require('@pnpm/local-resolver').default
resolveFromLocal({pref: './example-package'}, {prefix: process.cwd()})
resolveFromLocal({bareSpecifier: './example-package'}, {prefix: process.cwd()})
.then(resolveResult => console.log(resolveResult))
//> { id: 'link:example-package',
// normalizedPref: 'link:example-package',
// normalizedBareSpecifier: 'link:example-package',
// package:
// { name: 'foo',
// version: '1.0.0',

View File

@@ -1,5 +1,5 @@
'use strict'
const resolveFromLocal = require('@pnpm/local-resolver').default
resolveFromLocal({pref: './example-package'}, {prefix: process.cwd()})
resolveFromLocal({bareSpecifier: './example-package'}, {prefix: process.cwd()})
.then(resolveResult => console.log(resolveResult))

View File

@@ -10,12 +10,12 @@ import {
} from '@pnpm/resolver-base'
import { type DependencyManifest } from '@pnpm/types'
import { logger } from '@pnpm/logger'
import { parsePref, type WantedLocalDependency } from './parsePref'
import { parseBareSpecifier, type WantedLocalDependency } from './parseBareSpecifier'
export type { WantedLocalDependency }
export interface ResolveFromLocalResult extends ResolveResult {
specifier: string
normalizedBareSpecifier: string
resolution: TarballResolution | DirectoryResolution
manifest?: DependencyManifest
}
@@ -30,12 +30,12 @@ export async function resolveFromLocal (
projectDir: string
}
): Promise<ResolveFromLocalResult | null> {
const spec = parsePref(wantedDependency, opts.projectDir, opts.lockfileDir ?? opts.projectDir)
const spec = parseBareSpecifier(wantedDependency, opts.projectDir, opts.lockfileDir ?? opts.projectDir)
if (spec == null) return null
if (spec.type === 'file') {
return {
id: spec.id,
specifier: spec.normalizedPref,
normalizedBareSpecifier: spec.normalizedBareSpecifier,
resolution: {
integrity: await getTarballIntegrity(spec.fetchSpec),
tarball: spec.id,
@@ -84,7 +84,7 @@ export async function resolveFromLocal (
return {
id: spec.id,
manifest: localDependencyManifest,
specifier: spec.normalizedPref,
normalizedBareSpecifier: spec.normalizedBareSpecifier,
resolution: {
directory: spec.dependencyPath,
type: 'directory',

View File

@@ -15,37 +15,37 @@ export interface LocalPackageSpec {
fetchSpec: string
id: PkgResolutionId
type: 'directory' | 'file'
normalizedPref: string
normalizedBareSpecifier: string
}
export interface WantedLocalDependency {
pref: string
bareSpecifier: string
injected?: boolean
}
export function parsePref (
export function parseBareSpecifier (
wd: WantedLocalDependency,
projectDir: string,
lockfileDir: string
): LocalPackageSpec | null {
if (wd.pref.startsWith('link:') || wd.pref.startsWith('workspace:')) {
if (wd.bareSpecifier.startsWith('link:') || wd.bareSpecifier.startsWith('workspace:')) {
return fromLocal(wd, projectDir, lockfileDir, 'directory')
}
if (wd.pref.endsWith('.tgz') ||
wd.pref.endsWith('.tar.gz') ||
wd.pref.endsWith('.tar') ||
wd.pref.includes(path.sep) ||
wd.pref.startsWith('file:') ||
isFilespec.test(wd.pref)
if (wd.bareSpecifier.endsWith('.tgz') ||
wd.bareSpecifier.endsWith('.tar.gz') ||
wd.bareSpecifier.endsWith('.tar') ||
wd.bareSpecifier.includes(path.sep) ||
wd.bareSpecifier.startsWith('file:') ||
isFilespec.test(wd.bareSpecifier)
) {
const type = isFilename.test(wd.pref) ? 'file' : 'directory'
const type = isFilename.test(wd.bareSpecifier) ? 'file' : 'directory'
return fromLocal(wd, projectDir, lockfileDir, type)
}
if (wd.pref.startsWith('path:')) {
if (wd.bareSpecifier.startsWith('path:')) {
const err = new PnpmError('PATH_IS_UNSUPPORTED_PROTOCOL', 'Local dependencies via `path:` protocol are not supported. ' +
'Use the `link:` protocol for folder dependencies and `file:` for local tarballs')
// @ts-expect-error
err['pref'] = wd.pref
err['bareSpecifier'] = wd.bareSpecifier
// @ts-expect-error
err['protocol'] = 'path:'
@@ -55,35 +55,35 @@ export function parsePref (
}
function fromLocal (
{ pref, injected }: WantedLocalDependency,
{ bareSpecifier, injected }: WantedLocalDependency,
projectDir: string,
lockfileDir: string,
type: 'file' | 'directory'
): LocalPackageSpec {
const spec = pref.replace(/\\/g, '/')
const spec = bareSpecifier.replace(/\\/g, '/')
.replace(/^(?:file|link|workspace):\/*([A-Z]:)/i, '$1') // drive name paths on windows
.replace(/^(?:file|link|workspace):(?:\/*([~./]))?/, '$1')
let protocol!: string
if (pref.startsWith('file:')) {
if (bareSpecifier.startsWith('file:')) {
protocol = 'file:'
} else if (pref.startsWith('link:')) {
} else if (bareSpecifier.startsWith('link:')) {
protocol = 'link:'
} else {
protocol = type === 'directory' && !injected ? 'link:' : 'file:'
}
let fetchSpec!: string
let normalizedPref!: string
let normalizedBareSpecifier!: string
if (/^~\//.test(spec)) {
// this is needed for windows and for file:~/foo/bar
fetchSpec = resolvePath(os.homedir(), spec.slice(2))
normalizedPref = `${protocol}${spec}`
normalizedBareSpecifier = `${protocol}${spec}`
} else {
fetchSpec = resolvePath(projectDir, spec)
if (isAbsolute(spec)) {
normalizedPref = `${protocol}${spec}`
normalizedBareSpecifier = `${protocol}${spec}`
} else {
normalizedPref = `${protocol}${path.relative(projectDir, fetchSpec)}`
normalizedBareSpecifier = `${protocol}${path.relative(projectDir, fetchSpec)}`
}
}
@@ -101,7 +101,7 @@ function fromLocal (
dependencyPath,
fetchSpec,
id,
normalizedPref,
normalizedBareSpecifier,
type,
}
}

View File

@@ -8,9 +8,9 @@ import { logger } from '@pnpm/logger'
const TEST_DIR = path.dirname(require.resolve('@pnpm/tgz-fixtures/tgz/pnpm-local-resolver-0.1.1.tgz'))
test('resolve directory', async () => {
const resolveResult = await resolveFromLocal({ pref: '..' }, { projectDir: __dirname })
const resolveResult = await resolveFromLocal({ bareSpecifier: '..' }, { projectDir: __dirname })
expect(resolveResult!.id).toEqual('link:..')
expect(resolveResult!.specifier).toEqual('link:..')
expect(resolveResult!.normalizedBareSpecifier).toEqual('link:..')
expect(resolveResult!['manifest']!.name).toEqual('@pnpm/local-resolver')
expect((resolveResult!.resolution as DirectoryResolution).directory).toEqual(normalize(path.join(__dirname, '..')))
expect((resolveResult!.resolution as DirectoryResolution).type).toEqual('directory')
@@ -19,57 +19,57 @@ test('resolve directory', async () => {
test('resolve directory specified using absolute path', async () => {
const linkedDir = path.join(__dirname, '..')
const normalizedLinkedDir = normalize(linkedDir)
const resolveResult = await resolveFromLocal({ pref: `link:${linkedDir}` }, { projectDir: __dirname })
const resolveResult = await resolveFromLocal({ bareSpecifier: `link:${linkedDir}` }, { projectDir: __dirname })
expect(resolveResult!.id).toEqual('link:..')
expect(resolveResult!.specifier).toEqual(`link:${normalizedLinkedDir}`)
expect(resolveResult!.normalizedBareSpecifier).toEqual(`link:${normalizedLinkedDir}`)
expect(resolveResult!['manifest']!.name).toEqual('@pnpm/local-resolver')
expect((resolveResult!.resolution as DirectoryResolution).directory).toEqual(normalizedLinkedDir)
expect((resolveResult!.resolution as DirectoryResolution).type).toEqual('directory')
})
test('resolve injected directory', async () => {
const resolveResult = await resolveFromLocal({ injected: true, pref: '..' }, { projectDir: __dirname })
const resolveResult = await resolveFromLocal({ injected: true, bareSpecifier: '..' }, { projectDir: __dirname })
expect(resolveResult!.id).toEqual('file:..')
expect(resolveResult!.specifier).toEqual('file:..')
expect(resolveResult!.normalizedBareSpecifier).toEqual('file:..')
expect(resolveResult!['manifest']!.name).toEqual('@pnpm/local-resolver')
expect((resolveResult!.resolution as DirectoryResolution).directory).toEqual('..')
expect((resolveResult!.resolution as DirectoryResolution).type).toEqual('directory')
})
test('resolve workspace directory', async () => {
const resolveResult = await resolveFromLocal({ pref: 'workspace:..' }, { projectDir: __dirname })
const resolveResult = await resolveFromLocal({ bareSpecifier: 'workspace:..' }, { projectDir: __dirname })
expect(resolveResult!.id).toEqual('link:..')
expect(resolveResult!.specifier).toEqual('link:..')
expect(resolveResult!.normalizedBareSpecifier).toEqual('link:..')
expect(resolveResult!['manifest']!.name).toEqual('@pnpm/local-resolver')
expect((resolveResult!.resolution as DirectoryResolution).directory).toEqual(normalize(path.join(__dirname, '..')))
expect((resolveResult!.resolution as DirectoryResolution).type).toEqual('directory')
})
test('resolve directory specified using the file: protocol', async () => {
const resolveResult = await resolveFromLocal({ pref: 'file:..' }, { projectDir: __dirname })
const resolveResult = await resolveFromLocal({ bareSpecifier: 'file:..' }, { projectDir: __dirname })
expect(resolveResult!.id).toEqual('file:..')
expect(resolveResult!.specifier).toEqual('file:..')
expect(resolveResult!.normalizedBareSpecifier).toEqual('file:..')
expect(resolveResult!['manifest']!.name).toEqual('@pnpm/local-resolver')
expect((resolveResult!.resolution as DirectoryResolution).directory).toEqual('..')
expect((resolveResult!.resolution as DirectoryResolution).type).toEqual('directory')
})
test('resolve directory specified using the link: protocol', async () => {
const resolveResult = await resolveFromLocal({ pref: 'link:..' }, { projectDir: __dirname })
const resolveResult = await resolveFromLocal({ bareSpecifier: 'link:..' }, { projectDir: __dirname })
expect(resolveResult!.id).toEqual('link:..')
expect(resolveResult!.specifier).toEqual('link:..')
expect(resolveResult!.normalizedBareSpecifier).toEqual('link:..')
expect(resolveResult!['manifest']!.name).toEqual('@pnpm/local-resolver')
expect((resolveResult!.resolution as DirectoryResolution).directory).toEqual(normalize(path.join(__dirname, '..')))
expect((resolveResult!.resolution as DirectoryResolution).type).toEqual('directory')
})
test('resolve file', async () => {
const wantedDependency = { pref: './pnpm-local-resolver-0.1.1.tgz' }
const wantedDependency = { bareSpecifier: './pnpm-local-resolver-0.1.1.tgz' }
const resolveResult = await resolveFromLocal(wantedDependency, { projectDir: TEST_DIR })
expect(resolveResult).toEqual({
id: 'file:pnpm-local-resolver-0.1.1.tgz',
specifier: 'file:pnpm-local-resolver-0.1.1.tgz',
normalizedBareSpecifier: 'file:pnpm-local-resolver-0.1.1.tgz',
resolution: {
integrity: 'sha512-UHd2zKRT/w70KKzFlj4qcT81A1Q0H7NM9uKxLzIZ/VZqJXzt5Hnnp2PYPb5Ezq/hAamoYKIn5g7fuv69kP258w==',
tarball: 'file:pnpm-local-resolver-0.1.1.tgz',
@@ -79,7 +79,7 @@ test('resolve file', async () => {
})
test("resolve file when lockfile directory differs from the package's dir", async () => {
const wantedDependency = { pref: './pnpm-local-resolver-0.1.1.tgz' }
const wantedDependency = { bareSpecifier: './pnpm-local-resolver-0.1.1.tgz' }
const resolveResult = await resolveFromLocal(wantedDependency, {
lockfileDir: path.join(TEST_DIR, '..'),
projectDir: TEST_DIR,
@@ -87,7 +87,7 @@ test("resolve file when lockfile directory differs from the package's dir", asyn
expect(resolveResult).toEqual({
id: 'file:tgz/pnpm-local-resolver-0.1.1.tgz',
specifier: 'file:pnpm-local-resolver-0.1.1.tgz',
normalizedBareSpecifier: 'file:pnpm-local-resolver-0.1.1.tgz',
resolution: {
integrity: 'sha512-UHd2zKRT/w70KKzFlj4qcT81A1Q0H7NM9uKxLzIZ/VZqJXzt5Hnnp2PYPb5Ezq/hAamoYKIn5g7fuv69kP258w==',
tarball: 'file:tgz/pnpm-local-resolver-0.1.1.tgz',
@@ -97,12 +97,12 @@ test("resolve file when lockfile directory differs from the package's dir", asyn
})
test('resolve tarball specified with file: protocol', async () => {
const wantedDependency = { pref: 'file:./pnpm-local-resolver-0.1.1.tgz' }
const wantedDependency = { bareSpecifier: 'file:./pnpm-local-resolver-0.1.1.tgz' }
const resolveResult = await resolveFromLocal(wantedDependency, { projectDir: TEST_DIR })
expect(resolveResult).toEqual({
id: 'file:pnpm-local-resolver-0.1.1.tgz',
specifier: 'file:pnpm-local-resolver-0.1.1.tgz',
normalizedBareSpecifier: 'file:pnpm-local-resolver-0.1.1.tgz',
resolution: {
integrity: 'sha512-UHd2zKRT/w70KKzFlj4qcT81A1Q0H7NM9uKxLzIZ/VZqJXzt5Hnnp2PYPb5Ezq/hAamoYKIn5g7fuv69kP258w==',
tarball: 'file:pnpm-local-resolver-0.1.1.tgz',
@@ -113,7 +113,7 @@ test('resolve tarball specified with file: protocol', async () => {
test('fail when resolving tarball specified with the link: protocol', async () => {
try {
const wantedDependency = { pref: 'link:./pnpm-local-resolver-0.1.1.tgz' }
const wantedDependency = { bareSpecifier: 'link:./pnpm-local-resolver-0.1.1.tgz' }
await resolveFromLocal(wantedDependency, { projectDir: TEST_DIR })
fail()
} catch (err: any) { // eslint-disable-line
@@ -123,7 +123,7 @@ test('fail when resolving tarball specified with the link: protocol', async () =
})
test('fail when resolving from not existing directory an injected dependency', async () => {
const wantedDependency = { pref: 'file:./dir-does-not-exist' }
const wantedDependency = { bareSpecifier: 'file:./dir-does-not-exist' }
const projectDir = __dirname
await expect(
resolveFromLocal(wantedDependency, { projectDir })
@@ -132,7 +132,7 @@ test('fail when resolving from not existing directory an injected dependency', a
test('do not fail when resolving from not existing directory', async () => {
jest.spyOn(logger, 'warn')
const wantedDependency = { pref: 'link:./dir-does-not-exist' }
const wantedDependency = { bareSpecifier: 'link:./dir-does-not-exist' }
const resolveResult = await resolveFromLocal(wantedDependency, { projectDir: __dirname })
expect(resolveResult?.manifest).toStrictEqual({
name: 'dir-does-not-exist',
@@ -147,12 +147,12 @@ test('do not fail when resolving from not existing directory', async () => {
test('throw error when the path: protocol is used', async () => {
try {
await resolveFromLocal({ pref: 'path:..' }, { projectDir: __dirname })
await resolveFromLocal({ bareSpecifier: 'path:..' }, { projectDir: __dirname })
fail()
} catch (err: any) { // eslint-disable-line
expect(err).toBeDefined()
expect(err.code).toEqual('ERR_PNPM_PATH_IS_UNSUPPORTED_PROTOCOL')
expect(err.pref).toEqual('path:..')
expect(err.bareSpecifier).toEqual('path:..')
expect(err.protocol).toEqual('path:')
}
})

View File

@@ -27,7 +27,7 @@ const resolveFromNpm = createResolveFromNpm({
},
})
resolveFromNpm({alias: 'is-positive', pref: '1.0.0'}, {
resolveFromNpm({alias: 'is-positive', bareSpecifier: '1.0.0'}, {
registry: 'https://registry.npmjs.org/',
})
.then(resolveResult => console.log(JSON.stringify(resolveResult, null, 2)))

View File

@@ -9,7 +9,7 @@ const resolveFromNpm = createResolveFromNpm({
},
})
resolveFromNpm({alias: 'is-positive', pref: '1.0.0'}, {
resolveFromNpm({alias: 'is-positive', bareSpecifier: '1.0.0'}, {
registry: 'https://registry.npmjs.org/',
})
.then(resolveResult => console.log(JSON.stringify(resolveResult, null, 2)))

View File

@@ -35,10 +35,10 @@ import {
} from './pickPackage'
import {
parseJsrSpecifierToRegistryPackageSpec,
parsePref,
parseBareSpecifier,
type JsrRegistryPackageSpec,
type RegistryPackageSpec,
} from './parsePref'
} from './parseBareSpecifier'
import { fromRegistry, RegistryResponseError } from './fetch'
import { workspacePrefToNpm } from './workspacePrefToNpm'
import { whichVersionIsPinned } from './whichVersionIsPinned'
@@ -47,15 +47,15 @@ export class NoMatchingVersionError extends PnpmError {
public readonly packageMeta: PackageMeta
constructor (opts: { wantedDependency: WantedDependency, packageMeta: PackageMeta, registry: string }) {
const dep = opts.wantedDependency.alias
? `${opts.wantedDependency.alias}@${opts.wantedDependency.pref ?? ''}`
: opts.wantedDependency.pref!
? `${opts.wantedDependency.alias}@${opts.wantedDependency.bareSpecifier ?? ''}`
: opts.wantedDependency.bareSpecifier!
super('NO_MATCHING_VERSION', `No matching version found for ${dep} while fetching it from ${opts.registry}`)
this.packageMeta = opts.packageMeta
}
}
export {
parsePref,
parseBareSpecifier,
workspacePrefToNpm,
type PackageMeta,
type PackageMetaCache,
@@ -155,10 +155,10 @@ async function resolveNpm (
): Promise<ResolveResult | null> {
const defaultTag = opts.defaultTag ?? 'latest'
const registry = wantedDependency.alias
? pickRegistryForPackage(ctx.registries, wantedDependency.alias, wantedDependency.pref)
? pickRegistryForPackage(ctx.registries, wantedDependency.alias, wantedDependency.bareSpecifier)
: ctx.registries.default
if (wantedDependency.pref?.startsWith('workspace:')) {
if (wantedDependency.pref.startsWith('workspace:.')) return null
if (wantedDependency.bareSpecifier?.startsWith('workspace:')) {
if (wantedDependency.bareSpecifier.startsWith('workspace:.')) return null
const resolvedFromWorkspace = tryResolveFromWorkspace(wantedDependency, {
defaultTag,
lockfileDir: opts.lockfileDir,
@@ -176,8 +176,8 @@ async function resolveNpm (
}
}
const workspacePackages = opts.alwaysTryWorkspacePackages !== false ? opts.workspacePackages : undefined
const spec = wantedDependency.pref
? parsePref(wantedDependency.pref, wantedDependency.alias, defaultTag, registry)
const spec = wantedDependency.bareSpecifier
? parseBareSpecifier(wantedDependency.bareSpecifier, wantedDependency.alias, defaultTag, registry)
: defaultTagForAlias(wantedDependency.alias!, defaultTag)
if (spec == null) return null
@@ -273,9 +273,9 @@ async function resolveNpm (
integrity: getIntegrity(pickedPackage.dist),
tarball: pickedPackage.dist.tarball,
}
let specifier: string | undefined
let normalizedBareSpecifier: string | undefined
if (opts.calcSpecifier) {
specifier = spec.normalizedPref ?? calcSpecifier({
normalizedBareSpecifier = spec.normalizedBareSpecifier ?? calcSpecifier({
wantedDependency,
spec,
version: pickedPackage.version,
@@ -289,7 +289,7 @@ async function resolveNpm (
resolution,
resolvedVia: 'npm-registry',
publishedAt: meta.time?.[pickedPackage.version],
specifier,
normalizedBareSpecifier,
}
}
@@ -298,11 +298,11 @@ async function resolveJsr (
wantedDependency: WantedDependency,
opts: Omit<ResolveFromNpmOptions, 'registry'>
): Promise<ResolveResult | null> {
if (!wantedDependency.pref) return null
if (!wantedDependency.bareSpecifier) return null
const defaultTag = opts.defaultTag ?? 'latest'
const registry = ctx.registries['@jsr']! // '@jsr' is always defined
const spec = parseJsrSpecifierToRegistryPackageSpec(wantedDependency.pref, wantedDependency.alias, defaultTag)
const spec = parseJsrSpecifierToRegistryPackageSpec(wantedDependency.bareSpecifier, wantedDependency.alias, defaultTag)
if (spec == null) return null
const authHeaderValue = ctx.getAuthHeaderValueByURI(registry)
@@ -329,7 +329,7 @@ async function resolveJsr (
id,
latest: meta['dist-tags'].latest,
manifest: pickedPackage,
specifier: opts.calcSpecifier
normalizedBareSpecifier: opts.calcSpecifier
? calcJsrSpecifier({
wantedDependency,
spec,
@@ -371,7 +371,7 @@ function calcSpecifier ({
version: string
defaultPinnedVersion?: PinnedVersion
}): string {
if (wantedDependency.prevSpecifier === wantedDependency.pref && wantedDependency.prevSpecifier && versionSelectorType(wantedDependency.prevSpecifier)?.type === 'tag') {
if (wantedDependency.prevSpecifier === wantedDependency.bareSpecifier && wantedDependency.prevSpecifier && versionSelectorType(wantedDependency.prevSpecifier)?.type === 'tag') {
return wantedDependency.prevSpecifier
}
const range = calcRange(version, wantedDependency, defaultPinnedVersion)
@@ -384,7 +384,7 @@ function calcRange (version: string, wantedDependency: WantedDependency, default
return version
}
const pinnedVersion = (wantedDependency.prevSpecifier ? whichVersionIsPinned(wantedDependency.prevSpecifier) : undefined) ??
(wantedDependency.pref ? whichVersionIsPinned(wantedDependency.pref) : undefined) ??
(wantedDependency.bareSpecifier ? whichVersionIsPinned(wantedDependency.bareSpecifier) : undefined) ??
defaultPinnedVersion
return createVersionSpec(version, pinnedVersion)
}
@@ -404,13 +404,13 @@ function tryResolveFromWorkspace (
pinnedVersion?: PinnedVersion
}
): WorkspaceResolveResult | null {
if (!wantedDependency.pref?.startsWith('workspace:')) {
if (!wantedDependency.bareSpecifier?.startsWith('workspace:')) {
return null
}
const pref = workspacePrefToNpm(wantedDependency.pref)
const bareSpecifier = workspacePrefToNpm(wantedDependency.bareSpecifier)
const spec = parsePref(pref, wantedDependency.alias, opts.defaultTag, opts.registry)
if (spec == null) throw new Error(`Invalid workspace: spec (${wantedDependency.pref})`)
const spec = parseBareSpecifier(bareSpecifier, wantedDependency.alias, opts.defaultTag, opts.registry)
if (spec == null) throw new Error(`Invalid workspace: spec (${wantedDependency.bareSpecifier})`)
if (opts.workspacePackages == null) {
throw new Error('Cannot resolve package from workspace because opts.workspacePackages is not defined')
}
@@ -447,7 +447,7 @@ function tryResolveFromWorkspacePackages (
if (!workspacePkgsMatchingName) {
throw new PnpmError(
'WORKSPACE_PKG_NOT_FOUND',
`In ${path.relative(process.cwd(), opts.projectDir)}: "${spec.name}@${opts.wantedDependency.pref ?? ''}" is in the dependencies but no package named "${spec.name}" is present in the workspace`,
`In ${path.relative(process.cwd(), opts.projectDir)}: "${spec.name}@${opts.wantedDependency.bareSpecifier ?? ''}" is in the dependencies but no package named "${spec.name}" is present in the workspace`,
{
hint: 'Packages found in the workspace: ' + Object.keys(workspacePackages).join(', '),
}
@@ -460,7 +460,7 @@ function tryResolveFromWorkspacePackages (
if (!localVersion) {
throw new PnpmError(
'NO_MATCHING_VERSION_INSIDE_WORKSPACE',
`In ${path.relative(process.cwd(), opts.projectDir)}: No matching version found for ${opts.wantedDependency.alias ?? ''}@${opts.wantedDependency.pref ?? ''} inside the workspace`
`In ${path.relative(process.cwd(), opts.projectDir)}: No matching version found for ${opts.wantedDependency.alias ?? ''}@${opts.wantedDependency.bareSpecifier ?? ''} inside the workspace`
)
}
return resolveFromLocalPackage(workspacePkgsMatchingName.get(localVersion)!, spec, opts)
@@ -507,9 +507,9 @@ function resolveFromLocalPackage (
directory = localPackageDir
id = `link:${normalize(path.relative(opts.projectDir, localPackageDir))}` as PkgResolutionId
}
let specifier: string | undefined
let normalizedBareSpecifier: string | undefined
if (opts.calcSpecifier) {
specifier = spec.normalizedPref ?? calcSpecifierForWorkspaceDep({
normalizedBareSpecifier = spec.normalizedBareSpecifier ?? calcSpecifierForWorkspaceDep({
wantedDependency: opts.wantedDependency,
spec,
saveWorkspaceProtocol: opts.saveWorkspaceProtocol,
@@ -525,7 +525,7 @@ function resolveFromLocalPackage (
type: 'directory',
},
resolvedVia: 'workspace',
specifier,
normalizedBareSpecifier,
}
}
@@ -542,12 +542,12 @@ function calcSpecifierForWorkspaceDep ({
version: string
defaultPinnedVersion?: PinnedVersion
}): string {
if (!saveWorkspaceProtocol && !wantedDependency.pref?.startsWith('workspace:')) {
if (!saveWorkspaceProtocol && !wantedDependency.bareSpecifier?.startsWith('workspace:')) {
return calcSpecifier({ wantedDependency, spec, version, defaultPinnedVersion })
}
const prefix = (!wantedDependency.alias || spec.name === wantedDependency.alias) ? 'workspace:' : `workspace:${spec.name}@`
if (saveWorkspaceProtocol === 'rolling') {
const specifier = wantedDependency.prevSpecifier ?? wantedDependency.pref
const specifier = wantedDependency.prevSpecifier ?? wantedDependency.bareSpecifier
if (specifier) {
if ([`${prefix}*`, `${prefix}^`, `${prefix}~`].includes(specifier)) return specifier
const pinnedVersion = whichVersionIsPinned(specifier)

View File

@@ -6,29 +6,29 @@ export interface RegistryPackageSpec {
type: 'tag' | 'version' | 'range'
name: string
fetchSpec: string
normalizedPref?: string
normalizedBareSpecifier?: string
}
export function parsePref (
pref: string,
export function parseBareSpecifier (
bareSpecifier: string,
alias: string | undefined,
defaultTag: string,
registry: string
): RegistryPackageSpec | null {
let name = alias
if (pref.startsWith('npm:')) {
pref = pref.slice(4)
const index = pref.lastIndexOf('@')
if (bareSpecifier.startsWith('npm:')) {
bareSpecifier = bareSpecifier.slice(4)
const index = bareSpecifier.lastIndexOf('@')
if (index < 1) {
name = pref
pref = defaultTag
name = bareSpecifier
bareSpecifier = defaultTag
} else {
name = pref.slice(0, index)
pref = pref.slice(index + 1)
name = bareSpecifier.slice(0, index)
bareSpecifier = bareSpecifier.slice(index + 1)
}
}
if (name) {
const selector = getVersionSelectorType(pref)
const selector = getVersionSelectorType(bareSpecifier)
if (selector != null) {
return {
fetchSpec: selector.normalized,
@@ -37,13 +37,13 @@ export function parsePref (
}
}
}
if (pref.startsWith(registry)) {
const pkg = parseNpmTarballUrl(pref)
if (bareSpecifier.startsWith(registry)) {
const pkg = parseNpmTarballUrl(bareSpecifier)
if (pkg != null) {
return {
fetchSpec: pkg.version,
name: pkg.name,
normalizedPref: pref,
normalizedBareSpecifier: bareSpecifier,
type: 'version',
}
}

View File

@@ -15,7 +15,7 @@ import semver from 'semver'
import renameOverwrite from 'rename-overwrite'
import { toRaw } from './toRaw'
import { pickPackageFromMeta, pickVersionByVersionRange, pickLowestVersionByVersionRange } from './pickPackageFromMeta'
import { type RegistryPackageSpec } from './parsePref'
import { type RegistryPackageSpec } from './parseBareSpecifier'
export interface PackageMeta {
name: string

View File

@@ -2,7 +2,7 @@ import { PnpmError } from '@pnpm/error'
import { type VersionSelectors } from '@pnpm/resolver-base'
import semver from 'semver'
import util from 'util'
import { type RegistryPackageSpec } from './parsePref'
import { type RegistryPackageSpec } from './parseBareSpecifier'
import { type PackageInRegistry, type PackageMeta } from './pickPackage'
export type PickVersionByVersionRange = (

View File

@@ -1,4 +1,4 @@
import { type RegistryPackageSpec } from './parsePref'
import { type RegistryPackageSpec } from './parseBareSpecifier'
export function toRaw (spec: RegistryPackageSpec): string {
return `${spec.name}@${spec.fetchSpec}`

View File

@@ -1,9 +1,9 @@
import { WorkspaceSpec } from '@pnpm/workspace.spec-parser'
export function workspacePrefToNpm (workspacePref: string): string {
const parseResult = WorkspaceSpec.parse(workspacePref)
export function workspacePrefToNpm (workspaceBareSpecifier: string): string {
const parseResult = WorkspaceSpec.parse(workspaceBareSpecifier)
if (parseResult == null) {
throw new Error(`Invalid workspace spec: ${workspacePref}`)
throw new Error(`Invalid workspace spec: ${workspaceBareSpecifier}`)
}
const { alias, version } = parseResult

View File

@@ -57,11 +57,11 @@ test('resolveFromNpm()', async () => {
cacheDir,
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', pref: '1.0.0' }, { calcSpecifier: true })
const resolveResult = await resolveFromNpm({ alias: 'is-positive', bareSpecifier: '1.0.0' }, { calcSpecifier: true })
expect(resolveResult!.resolvedVia).toBe('npm-registry')
expect(resolveResult!.id).toBe('is-positive@1.0.0')
expect(resolveResult!.specifier).toBe('1.0.0')
expect(resolveResult!.normalizedBareSpecifier).toBe('1.0.0')
expect(resolveResult!.latest!.split('.').length).toBe(3)
expect(resolveResult!.resolution).toStrictEqual({
integrity: 'sha512-9cI+DmhNhA8ioT/3EJFnt0s1yehnAECyIOXdT+2uQGzcEEBaj8oNmVWj33+ZjPndMIFRQh8JeJlEu1uv5/J7pQ==',
@@ -89,7 +89,7 @@ test('resolveFromNpm() does not save mutated meta to the cache', async () => {
cacheDir,
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', pref: '1.0.0' }, {})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', bareSpecifier: '1.0.0' }, {})
resolveResult!.manifest!.version = '1000'
@@ -109,7 +109,7 @@ test('resolveFromNpm() should save metadata to a unique file when the package na
cacheDir,
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'JSON', pref: '1.0.0' }, {})
const resolveResult = await resolveFromNpm({ alias: 'JSON', bareSpecifier: '1.0.0' }, {})
expect(resolveResult!.resolvedVia).toBe('npm-registry')
expect(resolveResult!.id).toBe('JSON@1.0.0')
@@ -128,7 +128,7 @@ test('relative workspace protocol is skipped', async () => {
cacheDir,
registries,
})
const resolveResult = await resolveFromNpm({ pref: 'workspace:../is-positive' }, {
const resolveResult = await resolveFromNpm({ bareSpecifier: 'workspace:../is-positive' }, {
projectDir: '/home/istvan/src',
})
@@ -145,7 +145,7 @@ test('dry run', async () => {
cacheDir,
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', pref: '1.0.0' }, {
const resolveResult = await resolveFromNpm({ alias: 'is-positive', bareSpecifier: '1.0.0' }, {
dryRun: true,
})
@@ -165,7 +165,7 @@ test('dry run', async () => {
expect(fs.existsSync(path.join(cacheDir, resolveResult!.id, '..', 'index.json'))).toBeFalsy()
})
test('resolve to latest when no pref specified', async () => {
test('resolve to latest when no bareSpecifier specified', async () => {
nock(registries.default)
.get('/is-positive')
.reply(200, isPositiveMeta)
@@ -178,7 +178,7 @@ test('resolve to latest when no pref specified', async () => {
expect(resolveResult!.id).toBe('is-positive@3.1.0')
})
test('resolve to defaultTag when no pref specified', async () => {
test('resolve to defaultTag when no bareSpecifier specified', async () => {
nock(registries.default)
.get('/is-positive')
.reply(200, isPositiveMeta)
@@ -202,7 +202,7 @@ test('resolve to biggest non-deprecated version that satisfies the range', async
cacheDir: tempy.directory(),
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', pref: '3' }, {
const resolveResult = await resolveFromNpm({ alias: 'is-positive', bareSpecifier: '3' }, {
})
expect(resolveResult!.id).toBe('is-positive@3.0.0')
})
@@ -216,7 +216,7 @@ test('resolve to a deprecated version if there are no non-deprecated ones that s
cacheDir: tempy.directory(),
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', pref: '2' }, {})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', bareSpecifier: '2' }, {})
expect(resolveResult!.id).toBe('is-positive@2.0.0')
})
@@ -229,7 +229,7 @@ test('can resolve aliased dependency', async () => {
cacheDir: tempy.directory(),
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'positive', pref: 'npm:is-positive@1.0.0' }, {})
const resolveResult = await resolveFromNpm({ alias: 'positive', bareSpecifier: 'npm:is-positive@1.0.0' }, {})
expect(resolveResult!.id).toBe('is-positive@1.0.0')
})
@@ -242,7 +242,7 @@ test('can resolve aliased dependency w/o version specifier', async () => {
cacheDir: tempy.directory(),
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'positive', pref: 'npm:is-positive' }, {})
const resolveResult = await resolveFromNpm({ alias: 'positive', bareSpecifier: 'npm:is-positive' }, {})
expect(resolveResult!.id).toBe('is-positive@3.1.0')
})
@@ -255,12 +255,12 @@ test('can resolve aliased dependency w/o version specifier to default tag', asyn
cacheDir: tempy.directory(),
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'positive', pref: 'npm:is-positive' }, {
const resolveResult = await resolveFromNpm({ alias: 'positive', bareSpecifier: 'npm:is-positive' }, {
defaultTag: 'stable',
calcSpecifier: true,
})
expect(resolveResult!.id).toBe('is-positive@3.0.0')
expect(resolveResult!.specifier).toBe('npm:is-positive@^3.0.0')
expect(resolveResult!.normalizedBareSpecifier).toBe('npm:is-positive@^3.0.0')
})
test('can resolve aliased scoped dependency', async () => {
@@ -272,7 +272,7 @@ test('can resolve aliased scoped dependency', async () => {
cacheDir: tempy.directory(),
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'is', pref: 'npm:@sindresorhus/is@0.6.0' }, {})
const resolveResult = await resolveFromNpm({ alias: 'is', bareSpecifier: 'npm:@sindresorhus/is@0.6.0' }, {})
expect(resolveResult!.id).toBe('@sindresorhus/is@0.6.0')
})
@@ -285,7 +285,7 @@ test('can resolve aliased scoped dependency w/o version specifier', async () =>
cacheDir: tempy.directory(),
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'is', pref: 'npm:@sindresorhus/is' }, {})
const resolveResult = await resolveFromNpm({ alias: 'is', bareSpecifier: 'npm:@sindresorhus/is' }, {})
expect(resolveResult!.id).toBe('@sindresorhus/is@0.7.0')
})
@@ -298,7 +298,7 @@ test('can resolve package with version prefixed with v', async () => {
cacheDir: tempy.directory(),
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', pref: 'v1.0.0' }, {})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', bareSpecifier: 'v1.0.0' }, {})
expect(resolveResult!.id).toBe('is-positive@1.0.0')
})
@@ -311,7 +311,7 @@ test('can resolve package version loosely', async () => {
cacheDir: tempy.directory(),
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', pref: '= 1.0.0' }, {})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', bareSpecifier: '= 1.0.0' }, {})
expect(resolveResult!.id).toBe('is-positive@1.0.0')
})
@@ -329,7 +329,7 @@ test("resolves to latest if it's inside the wanted range. Even if there are newe
})
const resolveResult = await resolveFromNpm({
alias: 'is-positive',
pref: '^3.0.0',
bareSpecifier: '^3.0.0',
}, {})
// 3.1.0 is available but latest is 3.0.0, so preferring it
@@ -350,7 +350,7 @@ test("resolves to latest if it's inside the preferred range. Even if there are n
})
const resolveResult = await resolveFromNpm({
alias: 'is-positive',
pref: '^3.0.0',
bareSpecifier: '^3.0.0',
}, {
preferredVersions: {
'is-positive': { '^3.0.0': 'range' },
@@ -375,7 +375,7 @@ test("resolve using the wanted range, when it doesn't intersect with the preferr
})
const resolveResult = await resolveFromNpm({
alias: 'is-positive',
pref: '^3.0.0',
bareSpecifier: '^3.0.0',
}, {
preferredVersions: {
'is-positive': { '^2.0.0': 'range' },
@@ -399,7 +399,7 @@ test("use the preferred version if it's inside the wanted range", async () => {
})
const resolveResult = await resolveFromNpm({
alias: 'is-positive',
pref: '^3.0.0',
bareSpecifier: '^3.0.0',
}, {
preferredVersions: {
'is-positive': { '3.0.0': 'version' },
@@ -424,7 +424,7 @@ test("ignore the preferred version if it's not inside the wanted range", async (
})
const resolveResult = await resolveFromNpm({
alias: 'is-positive',
pref: '^3.0.0',
bareSpecifier: '^3.0.0',
}, {
preferredVersions: {
'is-positive': { '2.0.0': 'version' },
@@ -447,7 +447,7 @@ test('use the preferred range if it intersects with the wanted range', async ()
})
const resolveResult = await resolveFromNpm({
alias: 'is-positive',
pref: '>=1.0.0',
bareSpecifier: '>=1.0.0',
}, {
preferredVersions: {
'is-positive': { '^3.0.0': 'range' },
@@ -472,7 +472,7 @@ test('use the preferred range if it intersects with the wanted range (an array o
})
const resolveResult = await resolveFromNpm({
alias: 'is-positive',
pref: '>=1.0.0',
bareSpecifier: '>=1.0.0',
}, {
preferredVersions: {
'is-positive': {
@@ -500,7 +500,7 @@ test("ignore the preferred range if it doesn't intersect with the wanted range",
})
const resolveResult = await resolveFromNpm({
alias: 'is-positive',
pref: '^3.0.0',
bareSpecifier: '^3.0.0',
}, {
preferredVersions: {
'is-positive': { '^2.0.0': 'range' },
@@ -526,7 +526,7 @@ test("use the preferred dist-tag if it's inside the wanted range", async () => {
})
const resolveResult = await resolveFromNpm({
alias: 'is-positive',
pref: '^3.0.0',
bareSpecifier: '^3.0.0',
}, {
preferredVersions: {
'is-positive': { stable: 'tag' },
@@ -552,7 +552,7 @@ test("ignore the preferred dist-tag if it's not inside the wanted range", async
})
const resolveResult = await resolveFromNpm({
alias: 'is-positive',
pref: '^3.0.0',
bareSpecifier: '^3.0.0',
}, {
preferredVersions: {
'is-positive': { stable: 'tag' },
@@ -577,7 +577,7 @@ test("prefer a version that is both inside the wanted and preferred ranges. Even
})
const resolveResult = await resolveFromNpm({
alias: 'is-positive',
pref: '1.0.0 || 2.0.0',
bareSpecifier: '1.0.0 || 2.0.0',
}, {
preferredVersions: {
'is-positive': { '1.0.0 || 3.0.0': 'range' },
@@ -597,7 +597,7 @@ test('prefer the version that is matched by more preferred selectors', async ()
})
const resolveResult = await resolveFromNpm({
alias: 'is-positive',
pref: '^3.0.0',
bareSpecifier: '^3.0.0',
}, {
preferredVersions: {
'is-positive': { '^3.0.0': 'range', '3.0.0': 'version' },
@@ -618,7 +618,7 @@ test('prefer the version that has bigger weight in preferred selectors', async (
})
const resolveResult = await resolveFromNpm({
alias: 'is-positive',
pref: '^3.0.0',
bareSpecifier: '^3.0.0',
}, {
preferredVersions: {
'is-positive': {
@@ -640,7 +640,7 @@ test('offline resolution fails when package meta not found in the store', async
registries,
})
await expect(resolveFromNpm({ alias: 'is-positive', pref: '1.0.0' }, {})).rejects
await expect(resolveFromNpm({ alias: 'is-positive', bareSpecifier: '1.0.0' }, {})).rejects
.toThrow(
new PnpmError('NO_OFFLINE_META', `Failed to resolve is-positive@1.0.0 in package mirror ${path.join(cacheDir, ABBREVIATED_META_DIR, 'registry.npmjs.org/is-positive.json')}`)
)
@@ -661,7 +661,7 @@ test('offline resolution succeeds when package meta is found in the store', asyn
})
// This request will save the package's meta in the store
await resolveFromNpm({ alias: 'is-positive', pref: '1.0.0' }, {})
await resolveFromNpm({ alias: 'is-positive', bareSpecifier: '1.0.0' }, {})
}
{
@@ -671,7 +671,7 @@ test('offline resolution succeeds when package meta is found in the store', asyn
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', pref: '1.0.0' }, {})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', bareSpecifier: '1.0.0' }, {})
expect(resolveResult!.id).toBe('is-positive@1.0.0')
}
})
@@ -687,7 +687,7 @@ test('prefer offline resolution does not fail when package meta not found in the
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', pref: '1.0.0' }, {})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', bareSpecifier: '1.0.0' }, {})
expect(resolveResult!.id).toBe('is-positive@1.0.0')
})
@@ -708,7 +708,7 @@ test('when prefer offline is used, meta from store is used, where latest might b
})
// This request will save the package's meta in the store
await resolveFromNpm({ alias: 'is-positive', pref: '1.0.0' }, {})
await resolveFromNpm({ alias: 'is-positive', bareSpecifier: '1.0.0' }, {})
}
nock(registries.default)
@@ -725,7 +725,7 @@ test('when prefer offline is used, meta from store is used, where latest might b
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', pref: '^3.0.0' }, {})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', bareSpecifier: '^3.0.0' }, {})
expect(resolveResult!.id).toBe('is-positive@3.0.0')
}
@@ -743,7 +743,7 @@ test('error is thrown when package is not found in the registry', async () => {
cacheDir: tempy.directory(),
registries,
})
await expect(resolveFromNpm({ alias: notExistingPackage, pref: '1.0.0' }, {})).rejects
await expect(resolveFromNpm({ alias: notExistingPackage, bareSpecifier: '1.0.0' }, {})).rejects
.toThrow(
new RegistryResponseError(
{
@@ -770,7 +770,7 @@ test('error is thrown when registry not responding', async () => {
default: notExistingRegistry,
},
})
await expect(resolveFromNpm({ alias: notExistingPackage, pref: '1.0.0' }, {})).rejects
await expect(resolveFromNpm({ alias: notExistingPackage, bareSpecifier: '1.0.0' }, {})).rejects
.toThrow(new PnpmError('META_FETCH_FAIL', `GET ${notExistingRegistry}/${notExistingPackage}: request to ${notExistingRegistry}/${notExistingPackage} failed, reason: getaddrinfo ENOTFOUND not-existing.pnpm.io`, { attempts: 1 }))
})
@@ -785,7 +785,7 @@ test('extra info is shown if package has valid semver appended', async () => {
cacheDir: tempy.directory(),
registries,
})
await expect(resolveFromNpm({ alias: notExistingPackage, pref: '1.0.0' }, {})).rejects
await expect(resolveFromNpm({ alias: notExistingPackage, bareSpecifier: '1.0.0' }, {})).rejects
.toThrow(
new RegistryResponseError(
{
@@ -810,7 +810,7 @@ test('error is thrown when there is no package found for the requested version',
cacheDir: tempy.directory(),
registries,
})
const wantedDependency = { alias: 'is-positive', pref: '1000.0.0' }
const wantedDependency = { alias: 'is-positive', bareSpecifier: '1000.0.0' }
await expect(resolveFromNpm(wantedDependency, {})).rejects
.toThrow(
new NoMatchingVersionError({
@@ -830,7 +830,7 @@ test('error is thrown when package needs authorization', async () => {
cacheDir: tempy.directory(),
registries,
})
await expect(resolveFromNpm({ alias: 'needs-auth', pref: '*' }, {})).rejects
await expect(resolveFromNpm({ alias: 'needs-auth', bareSpecifier: '*' }, {})).rejects
.toThrow(
new RegistryResponseError(
{
@@ -855,7 +855,7 @@ test('error is thrown when there is no package found for the requested range', a
cacheDir: tempy.directory(),
registries,
})
const wantedDependency = { alias: 'is-positive', pref: '^1000.0.0' }
const wantedDependency = { alias: 'is-positive', bareSpecifier: '^1000.0.0' }
await expect(resolveFromNpm(wantedDependency, {})).rejects
.toThrow(
new NoMatchingVersionError({
@@ -875,7 +875,7 @@ test('error is thrown when there is no package found for the requested tag', asy
cacheDir: tempy.directory(),
registries,
})
const wantedDependency = { alias: 'is-positive', pref: 'unknown-tag' }
const wantedDependency = { alias: 'is-positive', bareSpecifier: 'unknown-tag' }
await expect(resolveFromNpm(wantedDependency, {})).rejects
.toThrow(
new NoMatchingVersionError({
@@ -901,7 +901,7 @@ test('resolveFromNpm() loads full metadata even if non-full metadata is already
cacheDir,
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', pref: '1.0.0' }, {})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', bareSpecifier: '1.0.0' }, {})
expect(resolveResult!.manifest!['scripts']).toBeFalsy()
}
@@ -911,7 +911,7 @@ test('resolveFromNpm() loads full metadata even if non-full metadata is already
cacheDir,
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', pref: '1.0.0' }, {})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', bareSpecifier: '1.0.0' }, {})
expect(resolveResult!.manifest!['scripts']).toBeTruthy()
}
})
@@ -928,7 +928,7 @@ test('resolve when tarball URL is requested from the registry', async () => {
})
const resolveResult = await resolveFromNpm({
alias: 'is-positive',
pref: `${registries.default}is-positive/-/is-positive-1.0.0.tgz`,
bareSpecifier: `${registries.default}is-positive/-/is-positive-1.0.0.tgz`,
}, {
calcSpecifier: true,
})
@@ -943,7 +943,7 @@ test('resolve when tarball URL is requested from the registry', async () => {
expect(resolveResult!.manifest).toBeTruthy()
expect(resolveResult!.manifest!.name).toBe('is-positive')
expect(resolveResult!.manifest!.version).toBe('1.0.0')
expect(resolveResult!.specifier).toBe(`${registries.default}is-positive/-/is-positive-1.0.0.tgz`)
expect(resolveResult!.normalizedBareSpecifier).toBe(`${registries.default}is-positive/-/is-positive-1.0.0.tgz`)
// The resolve function does not wait for the package meta cache file to be saved
// so we must delay for a bit in order to read it
@@ -963,7 +963,7 @@ test('resolve when tarball URL is requested from the registry and alias is not s
cacheDir,
registries,
})
const resolveResult = await resolveFromNpm({ pref: `${registries.default}is-positive/-/is-positive-1.0.0.tgz` }, { calcSpecifier: true })
const resolveResult = await resolveFromNpm({ bareSpecifier: `${registries.default}is-positive/-/is-positive-1.0.0.tgz` }, { calcSpecifier: true })
expect(resolveResult!.resolvedVia).toBe('npm-registry')
expect(resolveResult!.id).toBe('is-positive@1.0.0')
@@ -975,7 +975,7 @@ test('resolve when tarball URL is requested from the registry and alias is not s
expect(resolveResult!.manifest).toBeTruthy()
expect(resolveResult!.manifest!.name).toBe('is-positive')
expect(resolveResult!.manifest!.version).toBe('1.0.0')
expect(resolveResult!.specifier).toBe(`${registries.default}is-positive/-/is-positive-1.0.0.tgz`)
expect(resolveResult!.normalizedBareSpecifier).toBe(`${registries.default}is-positive/-/is-positive-1.0.0.tgz`)
// The resolve function does not wait for the package meta cache file to be saved
// so we must delay for a bit in order to read it
@@ -995,7 +995,7 @@ test('resolve from local directory when it matches the latest version of the pac
cacheDir,
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', pref: '1.0.0' }, {
const resolveResult = await resolveFromNpm({ alias: 'is-positive', bareSpecifier: '1.0.0' }, {
projectDir: '/home/istvan/src',
workspacePackages: new Map([
['is-positive', new Map([
@@ -1032,7 +1032,7 @@ test('resolve injected dependency from local directory when it matches the lates
cacheDir,
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', injected: true, pref: '1.0.0' }, {
const resolveResult = await resolveFromNpm({ alias: 'is-positive', injected: true, bareSpecifier: '1.0.0' }, {
projectDir: '/home/istvan/src',
lockfileDir: '/home/istvan/src',
workspacePackages: new Map([
@@ -1072,7 +1072,7 @@ test('do not resolve from local directory when alwaysTryWorkspacePackages is fal
cacheDir,
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', pref: '1.0.0' }, {
const resolveResult = await resolveFromNpm({ alias: 'is-positive', bareSpecifier: '1.0.0' }, {
alwaysTryWorkspacePackages: false,
projectDir: '/home/istvan/src',
workspacePackages: new Map([
@@ -1106,7 +1106,7 @@ test('resolve from local directory when alwaysTryWorkspacePackages is false but
cacheDir,
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', pref: 'workspace:*' }, {
const resolveResult = await resolveFromNpm({ alias: 'is-positive', bareSpecifier: 'workspace:*' }, {
alwaysTryWorkspacePackages: false,
projectDir: '/home/istvan/src',
workspacePackages: new Map([
@@ -1139,7 +1139,7 @@ test('resolve from local directory when alwaysTryWorkspacePackages is false but
cacheDir,
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'positive', pref: 'workspace:is-positive@*' }, {
const resolveResult = await resolveFromNpm({ alias: 'positive', bareSpecifier: 'workspace:is-positive@*' }, {
alwaysTryWorkspacePackages: false,
projectDir: '/home/istvan/src',
workspacePackages: new Map([
@@ -1180,7 +1180,7 @@ test('use version from the registry if it is newer than the local one', async ()
})
const resolveResult = await resolveFromNpm({
alias: 'is-positive',
pref: '^3.0.0',
bareSpecifier: '^3.0.0',
}, {
projectDir: '/home/istvan/src',
workspacePackages: new Map([
@@ -1222,7 +1222,7 @@ test('preferWorkspacePackages: use version from the workspace even if there is n
})
const resolveResult = await resolveFromNpm({
alias: 'is-positive',
pref: '^3.0.0',
bareSpecifier: '^3.0.0',
}, {
preferWorkspacePackages: true,
projectDir: '/home/istvan/src',
@@ -1262,7 +1262,7 @@ test('use local version if it is newer than the latest in the registry', async (
})
const resolveResult = await resolveFromNpm({
alias: 'is-positive',
pref: '^3.0.0',
bareSpecifier: '^3.0.0',
}, {
projectDir: '/home/istvan/src',
workspacePackages: new Map([
@@ -1300,7 +1300,7 @@ test('resolve from local directory when package is not found in the registry', a
cacheDir,
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', pref: '1' }, {
const resolveResult = await resolveFromNpm({ alias: 'is-positive', bareSpecifier: '1' }, {
projectDir: '/home/istvan/src/foo',
workspacePackages: new Map([
['is-positive', new Map([
@@ -1351,7 +1351,7 @@ test('resolve from local directory when package is not found in the registry and
cacheDir,
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', pref: 'latest' }, {
const resolveResult = await resolveFromNpm({ alias: 'is-positive', bareSpecifier: 'latest' }, {
projectDir: '/home/istvan/src',
workspacePackages: new Map([
['is-positive', new Map([
@@ -1402,7 +1402,7 @@ test('resolve from local directory when package is not found in the registry and
cacheDir,
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', pref: 'latest' }, {
const resolveResult = await resolveFromNpm({ alias: 'is-positive', bareSpecifier: 'latest' }, {
projectDir: '/home/istvan/src',
workspacePackages: new Map([
['is-positive', new Map([
@@ -1439,7 +1439,7 @@ test('resolve from local directory when package is not found in the registry and
cacheDir,
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', pref: '1.1.0' }, {
const resolveResult = await resolveFromNpm({ alias: 'is-positive', bareSpecifier: '1.1.0' }, {
projectDir: '/home/istvan/src/foo',
workspacePackages: new Map([
['is-positive', new Map([
@@ -1490,7 +1490,7 @@ test('resolve from local directory when the requested version is not found in th
cacheDir,
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', pref: '100.0.0' }, {
const resolveResult = await resolveFromNpm({ alias: 'is-positive', bareSpecifier: '100.0.0' }, {
projectDir: '/home/istvan/src/foo',
workspacePackages: new Map([
['is-positive', new Map([
@@ -1523,7 +1523,7 @@ test('workspace protocol: resolve from local directory even when it does not mat
cacheDir,
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', pref: 'workspace:^3.0.0' }, {
const resolveResult = await resolveFromNpm({ alias: 'is-positive', bareSpecifier: 'workspace:^3.0.0' }, {
projectDir: '/home/istvan/src',
workspacePackages: new Map([
['is-positive', new Map([
@@ -1560,7 +1560,7 @@ test('workspace protocol: resolve from local package that has a pre-release vers
cacheDir,
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', pref: 'workspace:*' }, {
const resolveResult = await resolveFromNpm({ alias: 'is-positive', bareSpecifier: 'workspace:*' }, {
projectDir: '/home/istvan/src',
workspacePackages: new Map([
['is-positive', new Map([
@@ -1597,7 +1597,7 @@ test("workspace protocol: don't resolve from local package that has a pre-releas
cacheDir,
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', pref: '2' }, {
const resolveResult = await resolveFromNpm({ alias: 'is-positive', bareSpecifier: '2' }, {
projectDir: '/home/istvan/src',
workspacePackages: new Map([
['is-positive', new Map([
@@ -1630,7 +1630,7 @@ test('workspace protocol: resolution fails if there is no matching local package
const projectDir = '/home/istvan/src'
let err!: Error & { code: string }
try {
await resolveFromNpm({ alias: 'is-positive', pref: 'workspace:^3.0.0' }, {
await resolveFromNpm({ alias: 'is-positive', bareSpecifier: 'workspace:^3.0.0' }, {
projectDir,
workspacePackages: new Map(),
})
@@ -1653,7 +1653,7 @@ test('workspace protocol: resolution fails if there is no matching local package
const projectDir = '/home/istvan/src'
let err!: Error & { code: string }
try {
await resolveFromNpm({ alias: 'is-positive', pref: 'workspace:^3.0.0' }, {
await resolveFromNpm({ alias: 'is-positive', bareSpecifier: 'workspace:^3.0.0' }, {
projectDir,
workspacePackages: new Map([
['is-positive', new Map([
@@ -1685,7 +1685,7 @@ test('workspace protocol: resolution fails if there are no local packages', asyn
let err!: Error
try {
await resolveFromNpm({ alias: 'is-positive', pref: 'workspace:^3.0.0' }, {
await resolveFromNpm({ alias: 'is-positive', bareSpecifier: 'workspace:^3.0.0' }, {
projectDir: '/home/istvan/src',
})
} catch (_err: any) { // eslint-disable-line
@@ -1717,7 +1717,7 @@ test('resolveFromNpm() should always return the name of the package that is spec
cacheDir,
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', pref: '3.1.0' }, {})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', bareSpecifier: '3.1.0' }, {})
expect(resolveResult!.resolvedVia).toBe('npm-registry')
expect(resolveResult!.id).toBe('is-positive@3.1.0')
@@ -1756,7 +1756,7 @@ test('request to metadata is retried if the received JSON is broken', async () =
registries,
cacheDir,
})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', pref: '1.0.0' }, {})!
const resolveResult = await resolveFromNpm({ alias: 'is-positive', bareSpecifier: '1.0.0' }, {})!
expect(resolveResult?.id).toBe('is-positive@1.0.0')
})
@@ -1823,7 +1823,7 @@ test('resolveFromNpm() does not fail if the meta file contains no integrity info
cacheDir,
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', pref: '2.0.0' }, {})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', bareSpecifier: '2.0.0' }, {})
expect(resolveResult!.resolvedVia).toBe('npm-registry')
expect(resolveResult!.id).toBe('is-positive@2.0.0')
@@ -1848,7 +1848,7 @@ test('resolveFromNpm() fails if the meta file contains invalid shasum', async ()
registries,
})
await expect(
resolveFromNpm({ alias: 'is-positive', pref: '1.0.0' }, {})
resolveFromNpm({ alias: 'is-positive', bareSpecifier: '1.0.0' }, {})
).rejects.toThrow('Tarball "https://registry.npmjs.org/is-positive/-/is-positive-1.0.0.tgz" has invalid shasum specified in its metadata: a')
})
@@ -1864,7 +1864,7 @@ test('resolveFromNpm() should normalize the registry', async () => {
default: 'https://reg.com/owner',
},
})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', pref: '1.0.0' }, {})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', bareSpecifier: '1.0.0' }, {})
expect(resolveResult!.resolvedVia).toBe('npm-registry')
expect(resolveResult!.id).toBe('is-positive@1.0.0')
@@ -1901,7 +1901,7 @@ test('pick lowest version by * when there are only prerelease versions', async (
cacheDir,
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'is-positive', pref: '*' }, {
const resolveResult = await resolveFromNpm({ alias: 'is-positive', bareSpecifier: '*' }, {
pickLowestVersion: true,
})

View File

@@ -44,7 +44,7 @@ test('fall back to a newer version if there is no version published by the given
fullMetadata: true,
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'bad-dates', pref: '^1.0.0' }, {
const resolveResult = await resolveFromNpm({ alias: 'bad-dates', bareSpecifier: '^1.0.0' }, {
publishedBy: new Date('2015-08-17T19:26:00.508Z'),
})
@@ -73,7 +73,7 @@ test('request metadata when the one in cache does not have a version satisfying
fullMetadata: true,
registries,
})
const resolveResult = await resolveFromNpm({ alias: 'bad-dates', pref: '^1.0.0' }, {
const resolveResult = await resolveFromNpm({ alias: 'bad-dates', bareSpecifier: '^1.0.0' }, {
publishedBy: new Date('2015-08-17T19:26:00.508Z'),
})

View File

@@ -51,7 +51,7 @@ test('resolveFromJsr() on jsr', async () => {
cacheDir,
registries,
})
const resolveResult = await resolveFromJsr({ alias: '@rus/greet', pref: 'jsr:0.0.3' }, { calcSpecifier: true })
const resolveResult = await resolveFromJsr({ alias: '@rus/greet', bareSpecifier: 'jsr:0.0.3' }, { calcSpecifier: true })
expect(resolveResult).toMatchObject({
resolvedVia: 'jsr-registry',
@@ -65,7 +65,7 @@ test('resolveFromJsr() on jsr', async () => {
integrity: expect.any(String),
tarball: 'https://npm.jsr.io/~/11/@jsr/rus__greet/0.0.3.tgz',
},
specifier: 'jsr:0.0.3',
normalizedBareSpecifier: 'jsr:0.0.3',
})
// The resolve function does not wait for the package meta cache file to be saved
@@ -96,7 +96,7 @@ test('resolveFromJsr() on jsr with alias renaming', async () => {
cacheDir,
registries,
})
const resolveResult = await resolveFromJsr({ alias: 'greet', pref: 'jsr:@rus/greet@0.0.3' }, {})
const resolveResult = await resolveFromJsr({ alias: 'greet', bareSpecifier: 'jsr:@rus/greet@0.0.3' }, {})
expect(resolveResult).toMatchObject({
resolvedVia: 'jsr-registry',
@@ -128,7 +128,7 @@ test('resolveFromJsr() on jsr with packages without scope', async () => {
cacheDir,
registries,
})
await expect(resolveFromJsr({ alias: 'greet', pref: 'jsr:0.0.3' }, {})).rejects.toMatchObject({
await expect(resolveFromJsr({ alias: 'greet', bareSpecifier: 'jsr:0.0.3' }, {})).rejects.toMatchObject({
code: 'ERR_PNPM_MISSING_JSR_PACKAGE_SCOPE',
})
})

View File

@@ -33,7 +33,7 @@ export async function testResolver (
resolution,
package,
latest,
normalizedPref,
normalizedBareSpecifier,
}
}
```

View File

@@ -45,7 +45,7 @@ export interface ResolveResult {
manifest?: DependencyManifest
resolution: Resolution
resolvedVia: 'npm-registry' | 'git-repository' | 'local-filesystem' | 'workspace' | 'url' | string
specifier?: string
normalizedBareSpecifier?: string
alias?: string
}
@@ -110,10 +110,10 @@ export type WantedDependency = {
prevSpecifier?: string
} & ({
alias?: string
pref: string
bareSpecifier: string
} | {
alias: string
pref?: string
bareSpecifier?: string
})
export type ResolveFunction = (wantedDependency: WantedDependency, opts: ResolveOptions) => Promise<ResolveResult>

View File

@@ -19,11 +19,11 @@ pnpm add @pnpm/tarball-resolver
'use strict'
const resolveFromTarball = require('@pnpm/tarball-resolver').default
resolveFromTarball({pref: 'http://registry.npmjs.org/is-array/-/is-array-1.0.1.tgz'})
resolveFromTarball({bareSpecifier: 'http://registry.npmjs.org/is-array/-/is-array-1.0.1.tgz'})
.then(resolveResult => console.log(JSON.stringify(resolveResult, null, 2)))
//> {
// "id": "registry.npmjs.org/is-array/-/is-array-1.0.1",
// "normalizedPref": "http://registry.npmjs.org/is-array/-/is-array-1.0.1.tgz",
// "normalizedBareSpecifier": "http://registry.npmjs.org/is-array/-/is-array-1.0.1.tgz",
// "resolution": {
// "tarball": "http://registry.npmjs.org/is-array/-/is-array-1.0.1.tgz"
// },

View File

@@ -1,5 +1,5 @@
'use strict'
const resolveFromTarball = require('@pnpm/tarball-resolver').default
resolveFromTarball({pref: 'http://registry.npmjs.org/is-array/-/is-array-1.0.1.tgz'})
resolveFromTarball({bareSpecifier: 'http://registry.npmjs.org/is-array/-/is-array-1.0.1.tgz'})
.then(resolveResult => console.log(JSON.stringify(resolveResult, null, 2)))

View File

@@ -3,20 +3,20 @@ import { type FetchFromRegistry } from '@pnpm/fetching-types'
export async function resolveFromTarball (
fetchFromRegistry: FetchFromRegistry,
wantedDependency: { pref: string }
wantedDependency: { bareSpecifier: string }
): Promise<ResolveResult | null> {
if (!wantedDependency.pref.startsWith('http:') && !wantedDependency.pref.startsWith('https:')) {
if (!wantedDependency.bareSpecifier.startsWith('http:') && !wantedDependency.bareSpecifier.startsWith('https:')) {
return null
}
if (isRepository(wantedDependency.pref)) return null
if (isRepository(wantedDependency.bareSpecifier)) return null
// If there are redirects, we want to get the final URL address
const { url: resolvedUrl } = await fetchFromRegistry(wantedDependency.pref, { method: 'HEAD' })
const { url: resolvedUrl } = await fetchFromRegistry(wantedDependency.bareSpecifier, { method: 'HEAD' })
return {
id: resolvedUrl as PkgResolutionId,
specifier: resolvedUrl,
normalizedBareSpecifier: resolvedUrl,
resolution: {
tarball: resolvedUrl,
},
@@ -30,15 +30,15 @@ const GIT_HOSTERS = new Set([
'bitbucket.org',
])
function isRepository (pref: string): boolean {
const url = new URL(pref)
function isRepository (bareSpecifier: string): boolean {
const url = new URL(bareSpecifier)
if (url.hash && url.hash.includes('/')) {
url.hash = encodeURIComponent(url.hash.substring(1))
pref = url.href
bareSpecifier = url.href
}
if (pref.endsWith('/')) {
pref = pref.slice(0, -1)
if (bareSpecifier.endsWith('/')) {
bareSpecifier = bareSpecifier.slice(0, -1)
}
const parts = pref.split('/')
const parts = bareSpecifier.split('/')
return (parts.length === 5 && GIT_HOSTERS.has(parts[2]))
}

View File

@@ -7,11 +7,11 @@ const fetch = createFetchFromRegistry({})
const resolveFromTarball = _resolveFromTarball.bind(null, fetch)
test('tarball from npm registry', async () => {
const resolutionResult = await resolveFromTarball({ pref: 'http://registry.npmjs.org/is-array/-/is-array-1.0.1.tgz' })
const resolutionResult = await resolveFromTarball({ bareSpecifier: 'http://registry.npmjs.org/is-array/-/is-array-1.0.1.tgz' })
expect(resolutionResult).toStrictEqual({
id: 'https://registry.npmjs.org/is-array/-/is-array-1.0.1.tgz',
specifier: 'https://registry.npmjs.org/is-array/-/is-array-1.0.1.tgz',
normalizedBareSpecifier: 'https://registry.npmjs.org/is-array/-/is-array-1.0.1.tgz',
resolution: {
tarball: 'https://registry.npmjs.org/is-array/-/is-array-1.0.1.tgz',
},
@@ -22,11 +22,11 @@ test('tarball from npm registry', async () => {
test('tarball from URL that contain port number', async () => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const fetch: any = async (url: string) => ({ url })
const resolutionResult = await _resolveFromTarball(fetch, { pref: 'http://buildserver.mycompany.com:81/my-private-package-0.1.6.tgz' })
const resolutionResult = await _resolveFromTarball(fetch, { bareSpecifier: 'http://buildserver.mycompany.com:81/my-private-package-0.1.6.tgz' })
expect(resolutionResult).toStrictEqual({
id: 'http://buildserver.mycompany.com:81/my-private-package-0.1.6.tgz',
specifier: 'http://buildserver.mycompany.com:81/my-private-package-0.1.6.tgz',
normalizedBareSpecifier: 'http://buildserver.mycompany.com:81/my-private-package-0.1.6.tgz',
resolution: {
tarball: 'http://buildserver.mycompany.com:81/my-private-package-0.1.6.tgz',
},
@@ -35,11 +35,11 @@ test('tarball from URL that contain port number', async () => {
})
test('tarball not from npm registry', async () => {
const resolutionResult = await resolveFromTarball({ pref: 'https://github.com/hegemonic/taffydb/tarball/master' })
const resolutionResult = await resolveFromTarball({ bareSpecifier: 'https://github.com/hegemonic/taffydb/tarball/master' })
expect(resolutionResult).toStrictEqual({
id: 'https://codeload.github.com/hegemonic/taffydb/legacy.tar.gz/refs/heads/master',
specifier: 'https://codeload.github.com/hegemonic/taffydb/legacy.tar.gz/refs/heads/master',
normalizedBareSpecifier: 'https://codeload.github.com/hegemonic/taffydb/legacy.tar.gz/refs/heads/master',
resolution: {
tarball: 'https://codeload.github.com/hegemonic/taffydb/legacy.tar.gz/refs/heads/master',
},
@@ -48,11 +48,11 @@ test('tarball not from npm registry', async () => {
})
test('tarballs from GitHub (is-negative)', async () => {
const resolutionResult = await resolveFromTarball({ pref: 'https://github.com/kevva/is-negative/archive/1d7e288222b53a0cab90a331f1865220ec29560c.tar.gz' })
const resolutionResult = await resolveFromTarball({ bareSpecifier: 'https://github.com/kevva/is-negative/archive/1d7e288222b53a0cab90a331f1865220ec29560c.tar.gz' })
expect(resolutionResult).toStrictEqual({
id: 'https://codeload.github.com/kevva/is-negative/tar.gz/1d7e288222b53a0cab90a331f1865220ec29560c',
specifier: 'https://codeload.github.com/kevva/is-negative/tar.gz/1d7e288222b53a0cab90a331f1865220ec29560c',
normalizedBareSpecifier: 'https://codeload.github.com/kevva/is-negative/tar.gz/1d7e288222b53a0cab90a331f1865220ec29560c',
resolution: {
tarball: 'https://codeload.github.com/kevva/is-negative/tar.gz/1d7e288222b53a0cab90a331f1865220ec29560c',
},
@@ -61,18 +61,18 @@ test('tarballs from GitHub (is-negative)', async () => {
})
test('ignore direct URLs to repositories', async () => {
expect(await resolveFromTarball({ pref: 'https://github.com/foo/bar' })).toBe(null)
expect(await resolveFromTarball({ pref: 'https://github.com/foo/bar/' })).toBe(null)
expect(await resolveFromTarball({ pref: 'https://gitlab.com/foo/bar' })).toBe(null)
expect(await resolveFromTarball({ pref: 'https://bitbucket.org/foo/bar' })).toBe(null)
expect(await resolveFromTarball({ bareSpecifier: 'https://github.com/foo/bar' })).toBe(null)
expect(await resolveFromTarball({ bareSpecifier: 'https://github.com/foo/bar/' })).toBe(null)
expect(await resolveFromTarball({ bareSpecifier: 'https://gitlab.com/foo/bar' })).toBe(null)
expect(await resolveFromTarball({ bareSpecifier: 'https://bitbucket.org/foo/bar' })).toBe(null)
})
test('ignore slash in hash', async () => {
// expect resolve from git.
let hash = 'path:/packages/simple-react-app'
expect(await resolveFromTarball({ pref: `RexSkz/test-git-subdir-fetch#${hash}` })).toBe(null)
expect(await resolveFromTarball({ pref: `RexSkz/test-git-subdir-fetch#${encodeURIComponent(hash)}` })).toBe(null)
expect(await resolveFromTarball({ bareSpecifier: `RexSkz/test-git-subdir-fetch#${hash}` })).toBe(null)
expect(await resolveFromTarball({ bareSpecifier: `RexSkz/test-git-subdir-fetch#${encodeURIComponent(hash)}` })).toBe(null)
hash = 'heads/canary'
expect(await resolveFromTarball({ pref: `zkochan/is-negative#${hash}` })).toBe(null)
expect(await resolveFromTarball({ pref: `zkochan/is-negative#${encodeURIComponent(hash)}` })).toBe(null)
expect(await resolveFromTarball({ bareSpecifier: `zkochan/is-negative#${hash}` })).toBe(null)
expect(await resolveFromTarball({ bareSpecifier: `zkochan/is-negative#${encodeURIComponent(hash)}` })).toBe(null)
})

View File

@@ -17,7 +17,7 @@ export type ManifestGetterOptions = Omit<ClientOptions, 'authConfig'>
export function createManifestGetter (
opts: ManifestGetterOptions
): (packageName: string, pref: string) => Promise<DependencyManifest | null> {
): (packageName: string, bareSpecifier: string) => Promise<DependencyManifest | null> {
const { resolve } = createResolver({ ...opts, authConfig: opts.rawConfig })
return getManifest.bind(null, resolve, opts)
}
@@ -26,9 +26,9 @@ export async function getManifest (
resolve: ResolveFunction,
opts: GetManifestOpts,
packageName: string,
pref: string
bareSpecifier: string
): Promise<DependencyManifest | null> {
const resolution = await resolve({ alias: packageName, pref }, {
const resolution = await resolve({ alias: packageName, bareSpecifier }, {
lockfileDir: opts.lockfileDir,
preferredVersions: {},
projectDir: opts.dir,

View File

@@ -14,7 +14,7 @@ import {
} from '@pnpm/lockfile.fs'
import { nameVerFromPkgSnapshot } from '@pnpm/lockfile.utils'
import { getAllDependenciesFromManifest } from '@pnpm/manifest-utils'
import { parsePref } from '@pnpm/npm-resolver'
import { parseBareSpecifier } from '@pnpm/npm-resolver'
import { pickRegistryForPackage } from '@pnpm/pick-registry-for-package'
import {
type DependenciesField,
@@ -132,12 +132,12 @@ export async function outdated (
const { name: packageName } = nameVerFromPkgSnapshot(relativeDepPath, pkgSnapshot)
const name = dp.parse(relativeDepPath).name ?? packageName
const pref = _replaceCatalogProtocolIfNecessary({ alias, pref: allDeps[alias] })
const bareSpecifier = _replaceCatalogProtocolIfNecessary({ alias, bareSpecifier: allDeps[alias] })
// If the npm resolve parser cannot parse the spec of the dependency,
// it means that the package is not from a npm-compatible registry.
// In that case, we can't check whether the package is up-to-date
if (
parsePref(pref, alias, 'latest', pickRegistryForPackage(opts.registries, name)) == null
parseBareSpecifier(bareSpecifier, alias, 'latest', pickRegistryForPackage(opts.registries, name)) == null
) {
if (current !== wanted) {
outdated.push({
@@ -155,7 +155,7 @@ export async function outdated (
const latestManifest = await opts.getLatestManifest(
name,
opts.compatible ? (pref ?? 'latest') : 'latest'
opts.compatible ? (bareSpecifier ?? 'latest') : 'latest'
)
if (latestManifest == null) return
@@ -205,7 +205,7 @@ function isEmpty (obj: object): boolean {
function replaceCatalogProtocolIfNecessary (catalogs: Catalogs, wantedDependency: WantedDependency) {
return matchCatalogResolveResult(resolveFromCatalog(catalogs, wantedDependency), {
unused: () => wantedDependency.pref,
unused: () => wantedDependency.bareSpecifier,
found: (found: CatalogResolutionFound) => found.resolution.specifier,
misconfiguration: (misconfiguration) => {
throw misconfiguration.error

View File

@@ -53,7 +53,7 @@ export async function handler (opts: CatIndexCommandOptions, params: string[]):
}
const wantedDependency = params[0]
const { alias, pref } = parseWantedDependency(wantedDependency) || {}
const { alias, bareSpecifier } = parseWantedDependency(wantedDependency) || {}
if (!alias) {
throw new PnpmError(
@@ -72,7 +72,7 @@ export async function handler (opts: CatIndexCommandOptions, params: string[]):
authConfig: opts.rawConfig,
})
const pkgSnapshot = await resolve(
{ alias, pref },
{ alias, bareSpecifier },
{
lockfileDir: opts.lockfileDir ?? opts.dir,
preferredVersions: {},
@@ -83,7 +83,7 @@ export async function handler (opts: CatIndexCommandOptions, params: string[]):
const filesIndexFile = getIndexFilePathInCafs(
storeDir,
(pkgSnapshot.resolution as TarballResolution).integrity!.toString(),
`${alias}@${pref}`
`${alias}@${bareSpecifier}`
)
try {
const pkgFilesIndex = await loadJsonFile<PackageFilesIndex>(filesIndexFile)

View File

@@ -10,7 +10,7 @@ async function main () {
const prefix = process.cwd()
const storeCtrl = await connectStoreController({ remotePrefix: 'http://localhost:5813' })
const response = await storeCtrl.requestPackage(
{ alias: 'is-positive', pref: '1.0.0' },
{ alias: 'is-positive', bareSpecifier: '1.0.0' },
{
downloadPriority: 0,
offline: false,

View File

@@ -51,7 +51,7 @@ test('server', async () => {
const storeCtrl = await connectStoreController({ remotePrefix, concurrency: 100 })
const projectDir = process.cwd()
const response = await storeCtrl.requestPackage(
{ alias: 'is-positive', pref: '1.0.0' },
{ alias: 'is-positive', bareSpecifier: '1.0.0' },
{
downloadPriority: 0,
lockfileDir: projectDir,
@@ -128,7 +128,7 @@ test('server errors should arrive to the client', async () => {
try {
const projectDir = process.cwd()
await storeCtrl.requestPackage(
{ alias: 'not-an-existing-package', pref: '1.0.0' },
{ alias: 'not-an-existing-package', bareSpecifier: '1.0.0' },
{
downloadPriority: 0,
lockfileDir: projectDir,

View File

@@ -147,7 +147,7 @@ export interface PackageResponse {
resolution: Resolution
manifest?: PackageManifest
id: PkgResolutionId
specifier?: string
normalizedBareSpecifier?: string
updated: boolean
publishedAt?: string
resolvedVia?: string

View File

@@ -59,14 +59,14 @@ export async function handler (
}
const { resolve } = createResolver({ ...opts, authConfig: opts.rawConfig })
const pkgName = 'pnpm'
const pref = params[0] ?? 'latest'
const resolution = await resolve({ alias: pkgName, pref }, {
const bareSpecifier = params[0] ?? 'latest'
const resolution = await resolve({ alias: pkgName, bareSpecifier }, {
lockfileDir: opts.lockfileDir ?? opts.dir,
preferredVersions: {},
projectDir: opts.dir,
})
if (!resolution?.manifest) {
throw new PnpmError('CANNOT_RESOLVE_PNPM', `Cannot find "${pref}" version of pnpm`)
throw new PnpmError('CANNOT_RESOLVE_PNPM', `Cannot find "${bareSpecifier}" version of pnpm`)
}
if (opts.wantedPackageManager?.name === packageManager.name && opts.managePackageManagerVersions) {
@@ -80,7 +80,7 @@ export async function handler (
}
}
if (resolution.manifest.version === packageManager.version) {
return `The currently active ${packageManager.name} v${packageManager.version} is already "${pref}" and doesn't need an update`
return `The currently active ${packageManager.name} v${packageManager.version} is already "${bareSpecifier}" and doesn't need an update`
}
const { baseDir, alreadyExisted } = await installPnpmToTools(resolution.manifest.version, opts)
@@ -90,6 +90,6 @@ export async function handler (
}
)
return alreadyExisted
? `The ${pref} version, v${resolution.manifest.version}, is already present on the system. It was activated by linking it from ${baseDir}.`
? `The ${bareSpecifier} version, v${resolution.manifest.version}, is already present on the system. It was activated by linking it from ${baseDir}.`
: undefined
}

View File

@@ -1,7 +1,7 @@
import path from 'path'
import npa from '@pnpm/npm-package-arg'
import { resolveWorkspaceRange } from '@pnpm/resolve-workspace-range'
import { parsePref, workspacePrefToNpm } from '@pnpm/npm-resolver'
import { parseBareSpecifier, workspacePrefToNpm } from '@pnpm/npm-resolver'
import { type ProjectRootDir, type BaseManifest } from '@pnpm/types'
import mapValues from 'ramda/src/map'
@@ -47,7 +47,7 @@ export function createPkgGraph<Pkg extends Package> (pkgs: Pkg[], opts?: {
const isWorkspaceSpec = rawSpec.startsWith('workspace:')
try {
if (isWorkspaceSpec) {
const { fetchSpec, name } = parsePref(workspacePrefToNpm(rawSpec), depName, 'latest', '')!
const { fetchSpec, name } = parseBareSpecifier(workspacePrefToNpm(rawSpec), depName, 'latest', '')!
rawSpec = fetchSpec
depName = name
}

View File

@@ -1,7 +1,7 @@
{
"name": "@pnpm/workspace.spec-parser",
"version": "1000.0.0",
"description": "Parse and stringify workspace pref",
"description": "Parse and stringify workspace specifier",
"keywords": [
"pnpm",
"pnpm10"

View File

@@ -9,8 +9,8 @@ export class WorkspaceSpec {
this.alias = alias
}
static parse (pref: string): WorkspaceSpec | null {
const parts = WORKSPACE_PREF_REGEX.exec(pref)
static parse (bareSpecifier: string): WorkspaceSpec | null {
const parts = WORKSPACE_PREF_REGEX.exec(bareSpecifier)
if (!parts?.groups) return null
return new WorkspaceSpec(parts.groups.version, parts.groups.alias)
}