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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions workspaces/arborist/lib/arborist/isolated-reifier.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ module.exports = cls => class IsolatedReifier extends cls {
const newChild = new IsolatedNode({
isInStore,
inBundle,
isRegistryDependency: node.isRegistryDependency,
location,
name: node.packageName || node.name,
optional: node.optional,
Expand Down Expand Up @@ -153,6 +154,9 @@ module.exports = cls => class IsolatedReifier extends cls {
result.optional = node.optional
result.resolved = node.resolved
result.version = node.version
// Carry the source node's registry-dependency flag so the store node retains it.
// IsolatedNode has no edges to recompute it from, and reify's registry-tarball allow-remote exemption depends on it.
result.isRegistryDependency = node.isRegistryDependency
return result
}

Expand Down
4 changes: 4 additions & 0 deletions workspaces/arborist/lib/isolated-classes.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ class IsolatedNode {
inventory = new IsolatedInventory()
isInStore = false
inBundle = false
isRegistryDependency = false
linksIn = new Set()
meta = { loadedFromDisk: false }
optional = false
Expand Down Expand Up @@ -50,6 +51,9 @@ class IsolatedNode {
if (options.inBundle) {
this.inBundle = true
}
if (options.isRegistryDependency) {
this.isRegistryDependency = true
}
if (options.optional) {
this.optional = true
}
Expand Down
50 changes: 50 additions & 0 deletions workspaces/arborist/test/arborist/reify.js
Original file line number Diff line number Diff line change
Expand Up @@ -3854,6 +3854,56 @@ t.test('should preserve exact ranges, missing actual tree', async (t) => {
await t.resolves(arb.reify(), 'same-origin tarball is allowed for registry root')
})

t.test('allowRemote=none allows registry tarball under linked install strategy', async t => {
// The linked strategy extracts store nodes as IsolatedNode, which has no edges to recompute isRegistryDependency from.
// The flag must be carried from the source tree node so the registry-tarball allow-remote exemption still applies.
const abbrevPackument5 = JSON.stringify({
_id: 'abbrev',
_rev: 'lkjadflkjasdf',
name: 'abbrev',
'dist-tags': { latest: '1.1.1' },
versions: {
'1.1.1': {
name: 'abbrev',
version: '1.1.1',
dist: {
tarball: 'https://registry.example.com/npm/abbrev/-/abbrev-1.1.1.tgz',
},
},
},
})

const testdir = t.testdir({
project: {
'package.json': JSON.stringify({
name: 'myproject',
version: '1.0.0',
dependencies: {
abbrev: '1.1.1',
},
}),
},
})

tnock(t, 'https://registry.example.com')
.get('/npm/abbrev')
.reply(200, abbrevPackument5)

tnock(t, 'https://registry.example.com')
.get('/npm/abbrev/-/abbrev-1.1.1.tgz')
.reply(200, abbrevTGZ)

const arb = new Arborist({
path: resolve(testdir, 'project'),
registry: 'https://registry.example.com/npm',
cache: resolve(testdir, 'cache'),
allowRemote: 'none',
installStrategy: 'linked',
})

await t.resolves(arb.reify(), 'registry tarball is allowed under linked strategy')
})

t.test('registry with different protocol should swap protocol', async (t) => {
const abbrevPackument4 = JSON.stringify({
_id: 'abbrev',
Expand Down
1 change: 1 addition & 0 deletions workspaces/arborist/test/script-allowed.js
Original file line number Diff line number Diff line change
Expand Up @@ -402,6 +402,7 @@ t.test('isolated mode (linked): bundled IsolatedNode is blocked', async t => {

const store = new IsolatedNode({
isInStore: true,
isRegistryDependency: true, // carried from the source node by #externalProxy
location: 'node_modules/.store/store-pkg@1.0.0/node_modules/store-pkg',
name: 'store-pkg',
package: { name: 'store-pkg', version: '1.0.0' },
Expand Down
Loading