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
13 changes: 11 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -147,15 +147,24 @@ Options object is cloned, and mutated along the way to add integrity, resolved,
There must be a configured `_keys` entry in the config that is scoped to the registry the manifest is being fetched from.
* `tufCache` Where to store metadata/target files when retrieving the package attestation key material via TUF.
Defaults to the same cache directory that npm will use by default, based on platform and environment.
* `allowGit` Whether or not to allow data to be fetched from git.
* `allowGit` Whether or not to allow data to be fetched from a git spec.
Possible values are `all`, `none`, or `root`.
Defaults to `all`.
`all` means git is allowed
`none` means git is not allowed
`root` means that git is only allowed if fetching from a root context.
Context for whether or not the package being fetched is `root` is set via the `_isRoot` option.
* `allowRemote` Whether or not to allow data to be fetched from remote specs.
Possible values and defaults are the same as `allowGit`
* `allowFile` Whether or not to allow data to be fetched from file specs.
Possible values and defaults are the same as `allowGit`
* `allowDirectory` Whether or not to allow data to be fetched from directory specs.
Possible values and defaults are the same as `allowGit`
* `_isRoot` Whether or not the package being fetched is in a root context.
For `npm` itself this means a package that is defined in the local project or workspace package.json, or a package that is being fetched for another command like `npm view`.
Defaults to `false`,
For `npm` itself this means a package that is defined in the local project or workspace package.json, or a package that is being fetched for another command like `npm view`. This informs the `allowX` options to let them know the context of the current request.

For more info on spec types (i.e. git, remote) see [npm-package-arg](npm.im/npm-package-arg)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will the link work without the protocol prefix here, or will it interpret as a relative path?

Copy link
Member Author

@wraithgar wraithgar Feb 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I copied it verbatim from another link to the same repo in the readme which already works


### Advanced API

Expand Down
23 changes: 12 additions & 11 deletions lib/fetcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -470,33 +470,32 @@ const DirFetcher = require('./dir.js')
const RemoteFetcher = require('./remote.js')

// possible values for allow: 'all', 'root', 'none'
const canUseGit = (allow = 'all', isRoot = false) => {
const canUse = ({ allow = 'all', isRoot = false, allowType, spec }) => {
if (allow === 'all') {
return true
}
if (allow !== 'none' && isRoot) {
return true
}
return false
throw Object.assign(
new Error(`Fetching${allow === 'root' ? ' non-root' : ''} packages of type "${allowType}" have been disabled`),
{
code: `EALLOW${allowType.toUpperCase()}`,
package: spec.toString(),
}
)
}

// Get an appropriate fetcher object from a spec and options
FetcherBase.get = (rawSpec, opts = {}) => {
const spec = npa(rawSpec, opts.where)
switch (spec.type) {
case 'git':
if (!canUseGit(opts.allowGit, opts._isRoot)) {
throw Object.assign(
new Error(`Fetching${opts.allowGit === 'root' ? ' non-root' : ''} packages from git has been disabled`),
{
code: 'EALLOWGIT',
package: spec.toString(),
}
)
}
canUse({ allow: opts.allowGit, isRoot: opts._isRoot, allowType: 'git', spec })
return new GitFetcher(spec, opts)

case 'remote':
canUse({ allow: opts.allowRemote, isRoot: opts._isRoot, allowType: 'remote', spec })
return new RemoteFetcher(spec, opts)

case 'version':
Expand All @@ -506,9 +505,11 @@ FetcherBase.get = (rawSpec, opts = {}) => {
return new RegistryFetcher(spec.subSpec || spec, opts)

case 'file':
canUse({ allow: opts.allowFile, isRoot: opts._isRoot, allowType: 'file', spec })
return new FileFetcher(spec, opts)

case 'directory':
canUse({ allow: opts.allowDirectory, isRoot: opts._isRoot, allowType: 'directory', spec })
return new DirFetcher(spec, opts)

default:
Expand Down
37 changes: 24 additions & 13 deletions test/fetcher.js
Original file line number Diff line number Diff line change
Expand Up @@ -536,19 +536,30 @@ t.test('fetcher.get', t => {
t.end()
})

t.test('allowGit', t => {
t.ok(Fetcher.get('npm/repo'), 'defaults')
t.ok(Fetcher.get('npm/foo', { allowGit: 'all' }), 'allowGit: all')
t.ok(Fetcher.get('npm/foo', { allowGit: 'root', _isRoot: true }), 'allowGit: root')
t.throws(() => {
Fetcher.get('npm/foo', { allowGit: 'none' })
}, { code: 'EALLOWGIT' })
t.throws(() => {
Fetcher.get('npm/foo', { allowGit: 'root' })
}, { code: 'EALLOWGIT' })
t.throws(() => {
Fetcher.get('npm/foo', { allowGit: 'root', _isRoot: false })
}, { code: 'EALLOWGIT' })
t.test('allowX', t => {
const allowTypes = [
['allowGit', 'npm/foo'],
['allowRemote', 'http://npmjs.org/package'],
['allowFile', './local.tgz'],
['allowDirectory', './local/dir'],
]
for (const [allowType, spec] of allowTypes) {
t.test(`${allowType}: ${spec}`, t => {
t.ok(Fetcher.get(spec), 'defaults')
t.ok(Fetcher.get(spec, { [allowType]: 'all' }), `${allowType}: all`)
t.ok(Fetcher.get(spec, { [allowType]: 'root', _isRoot: true }), `${allowType}: root`)
t.throws(() => {
Fetcher.get(spec, { [allowType]: 'none' })
}, { code: `E${allowType.toUpperCase()}` })
t.throws(() => {
Fetcher.get(spec, { [allowType]: 'root' })
}, { code: `E${allowType.toUpperCase()}` })
t.throws(() => {
Fetcher.get(spec, { [allowType]: 'root', _isRoot: false })
}, { code: `E${allowType.toUpperCase()}` })
t.end()
})
}
t.end()
})

Expand Down
Loading