fix: allow workspace package name with scope (#3899)

Co-authored-by: Javier <javier.garcia@meteologica.com>
Co-authored-by: Zoltan Kochan <z@kochan.io>
This commit is contained in:
Erik Yu
2021-10-21 18:34:39 +08:00
committed by GitHub
parent e416357358
commit 82caa0b568
5 changed files with 52 additions and 81 deletions

View File

@@ -0,0 +1,5 @@
---
"@pnpm/npm-resolver": patch
---
It should be possible to alias scoped packages using the `workspace:` protocol. See https://github.com/pnpm/pnpm/issues/3883

View File

@@ -29,6 +29,7 @@ import parsePref, {
} from './parsePref'
import fromRegistry, { RegistryResponseError } from './fetch'
import createPkgId from './createNpmPkgId'
import workspacePrefToNpm from './workspacePrefToNpm'
export class NoMatchingVersionError extends PnpmError {
public readonly packageMeta: PackageMeta
@@ -196,23 +197,6 @@ async function resolveNpm (
}
}
function workspacePrefToNpm (workspacePref: string): string {
const prefParts = /^workspace:([^@]+@)?(.*)$/.exec(workspacePref)
if (prefParts == null) {
throw new Error(`Invalid workspace spec: ${workspacePref}`)
}
const [workspacePkgAlias, workspaceVersion] = prefParts.slice(1)
const pkgAliasPart = workspacePkgAlias != null && workspacePkgAlias
? `npm:${workspacePkgAlias}`
: ''
const versionPart = workspaceVersion === '^' || workspaceVersion === '~'
? '*'
: workspaceVersion
return `${pkgAliasPart}${versionPart}`
}
function tryResolveFromWorkspace (
wantedDependency: WantedDependency,
opts: {

View File

@@ -0,0 +1,17 @@
export default function workspacePrefToNpm (workspacePref: string): string {
const prefParts = /^workspace:([^._/][^@]*@)?(.*)$/.exec(workspacePref)
if (prefParts == null) {
throw new Error(`Invalid workspace spec: ${workspacePref}`)
}
const [workspacePkgAlias, workspaceVersion] = prefParts.slice(1)
const pkgAliasPart = workspacePkgAlias != null && workspacePkgAlias
? `npm:${workspacePkgAlias}`
: ''
const versionPart = workspaceVersion === '^' || workspaceVersion === '~'
? '*'
: workspaceVersion
return `${pkgAliasPart}${versionPart}`
}

View File

@@ -1589,70 +1589,6 @@ test('request to a package with malformed metadata', async () => {
)
})
test('resolve workspace:^', async () => {
const cacheDir = tempy.directory()
const resolve = createResolveFromNpm({
cacheDir,
})
const resolveResult = await resolve({ alias: 'is-positive', pref: 'workspace:^' }, {
projectDir: '/home/istvan/src',
registry,
workspacePackages: {
'is-positive': {
'1.0.0': {
dir: '/home/istvan/src/is-positive',
manifest: {
name: 'is-positive',
version: '1.0.0',
},
},
},
},
})
expect(resolveResult!.resolvedVia).toBe('local-filesystem')
expect(resolveResult!.id).toBe('link:is-positive')
expect(resolveResult!.resolution).toStrictEqual({
directory: '/home/istvan/src/is-positive',
type: 'directory',
})
expect(resolveResult!.manifest).toBeTruthy()
expect(resolveResult!.manifest!.name).toBe('is-positive')
expect(resolveResult!.manifest!.version).toBe('1.0.0')
})
test('resolve workspace:~', async () => {
const cacheDir = tempy.directory()
const resolve = createResolveFromNpm({
cacheDir,
})
const resolveResult = await resolve({ alias: 'is-positive', pref: 'workspace:~' }, {
projectDir: '/home/istvan/src',
registry,
workspacePackages: {
'is-positive': {
'1.0.0': {
dir: '/home/istvan/src/is-positive',
manifest: {
name: 'is-positive',
version: '1.0.0',
},
},
},
},
})
expect(resolveResult!.resolvedVia).toBe('local-filesystem')
expect(resolveResult!.id).toBe('link:is-positive')
expect(resolveResult!.resolution).toStrictEqual({
directory: '/home/istvan/src/is-positive',
type: 'directory',
})
expect(resolveResult!.manifest).toBeTruthy()
expect(resolveResult!.manifest!.name).toBe('is-positive')
expect(resolveResult!.manifest!.version).toBe('1.0.0')
})
test('resolveFromNpm() does not fail if the meta file contains no integrity information', async () => {
nock(registry)
.get('/is-positive')

View File

@@ -0,0 +1,29 @@
import workspacePrefToNpm from '@pnpm/npm-resolver/lib/workspacePrefToNpm'
describe('workspacePrefToNpm', () => {
test('resolve workspace only version aliases', async () => {
expect(workspacePrefToNpm('workspace:^')).toStrictEqual('*')
expect(workspacePrefToNpm('workspace:~')).toStrictEqual('*')
})
test('resolve package name aliases', async () => {
expect(workspacePrefToNpm('workspace:is-positive@3.0.0')).toStrictEqual('npm:is-positive@3.0.0')
expect(workspacePrefToNpm('workspace:is-positive@*')).toStrictEqual('npm:is-positive@*')
expect(workspacePrefToNpm('workspace:is-positive@^')).toStrictEqual('npm:is-positive@*')
})
test('resolve scoped package name aliases', async () => {
expect(
workspacePrefToNpm('workspace:@scope/is-positive@1.2.3')
).toStrictEqual('npm:@scope/is-positive@1.2.3')
expect(
workspacePrefToNpm('workspace:@scope/is-positive@^1.2.3')
).toStrictEqual('npm:@scope/is-positive@^1.2.3')
expect(
workspacePrefToNpm('workspace:@scope/is-positive@*')
).toStrictEqual('npm:@scope/is-positive@*')
expect(
workspacePrefToNpm('workspace:@scope/is-positive@~')
).toStrictEqual('npm:@scope/is-positive@*')
})
})