Skip to content

Commit

Permalink
feat: add package-lock-only mode to npm query
Browse files Browse the repository at this point in the history
  • Loading branch information
wraithgar committed Aug 23, 2023
1 parent c736b62 commit f239540
Show file tree
Hide file tree
Showing 5 changed files with 126 additions and 2 deletions.
6 changes: 6 additions & 0 deletions docs/lib/content/commands/npm-query.md
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,12 @@ npm query ":type(git)" | jq 'map(.name)' | xargs -I {} npm why {}
},
...
```
### Package lock only mode

If package-lock-only is enabled, only the information in the package
lock (or shrinkwrap) is loaded. This means that information from the
package.json files of your dependencies will not be included in the
result set (e.g. description, homepage, engines).

### Configuration

Expand Down
13 changes: 12 additions & 1 deletion lib/commands/query.js
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class Query extends BaseCommand {
'workspace',
'workspaces',
'include-workspace-root',
'package-lock-only',
]

get parsedResponse () {
Expand All @@ -64,7 +65,17 @@ class Query extends BaseCommand {
forceActual: true,
}
const arb = new Arborist(opts)
const tree = await arb.loadActual(opts)
let tree
if (this.npm.config.get('package-lock-only')) {
try {
tree = await arb.loadVirtual()
} catch (err) {
/* eslint-disable-next-line max-len */
throw this.usageError('A package lock or shrinkwrap file is required in package-lock-only mode')
}
} else {
tree = await arb.loadActual(opts)
}
const items = await tree.querySelectorAll(args[0], this.npm.flatOptions)
this.buildResponse(items)

Expand Down
48 changes: 48 additions & 0 deletions tap-snapshots/test/lib/commands/query.js.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,54 @@ exports[`test/lib/commands/query.js TAP linked node > should return linked node
]
`

exports[`test/lib/commands/query.js TAP package-lock-only with package lock > should return valid response with only lock info 1`] = `
[
{
"name": "project",
"dependencies": {
"a": "^1.0.0"
},
"pkgid": "project@",
"location": "",
"path": "{CWD}/prefix",
"realpath": "{CWD}/prefix",
"resolved": null,
"from": [],
"to": [
"node_modules/a"
],
"dev": false,
"inBundle": false,
"deduped": false,
"overridden": false,
"queryContext": {}
},
{
"version": "1.2.3",
"resolved": "https://dummy.npmjs.org/a/-/a-1.2.3.tgz",
"integrity": "sha512-dummy",
"engines": {
"node": ">=14.17"
},
"name": "a",
"_id": "a@1.2.3",
"pkgid": "a@1.2.3",
"location": "node_modules/a",
"path": "{CWD}/prefix/node_modules/a",
"realpath": "{CWD}/prefix/node_modules/a",
"from": [
""
],
"to": [],
"dev": false,
"inBundle": false,
"deduped": false,
"overridden": false,
"queryContext": {}
}
]
`

exports[`test/lib/commands/query.js TAP recursive tree > should return everything in the tree, accounting for recursion 1`] = `
[
{
Expand Down
3 changes: 2 additions & 1 deletion tap-snapshots/test/lib/docs.js.test.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -3766,7 +3766,7 @@ npm query <selector>
Options:
[-g|--global]
[-w|--workspace <workspace-name> [-w|--workspace <workspace-name> ...]]
[-ws|--workspaces] [--include-workspace-root]
[-ws|--workspaces] [--include-workspace-root] [--package-lock-only]
Run "npm help query" for more info
Expand All @@ -3778,6 +3778,7 @@ npm query <selector>
#### \`workspace\`
#### \`workspaces\`
#### \`include-workspace-root\`
#### \`package-lock-only\`
`

exports[`test/lib/docs.js TAP usage rebuild > must match snapshot 1`] = `
Expand Down
58 changes: 58 additions & 0 deletions test/lib/commands/query.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,3 +179,61 @@ t.test('global', async t => {
await npm.exec('query', ['[name=lorem]'])
t.matchSnapshot(joinedOutput(), 'should return global package')
})

t.test('package-lock-only', t => {
t.test('no package lock', async t => {
const { npm } = await loadMockNpm(t, {
config: {
'package-lock-only': true,
},
prefixDir: {
'package.json': JSON.stringify({
name: 'project',
dependencies: {
a: '^1.0.0',
},
}),
},
})
await t.rejects(npm.exec('query', [':root, :root > *']), { code: 'EUSAGE' })
})

t.test('with package lock', async t => {
const { npm, joinedOutput } = await loadMockNpm(t, {
config: {
'package-lock-only': true,
},
prefixDir: {
'package.json': JSON.stringify({
name: 'project',
dependencies: {
a: '^1.0.0',
},
}),
'package-lock.json': JSON.stringify({
name: 'project',
lockfileVersion: 3,
requires: true,
packages: {
'': {
dependencies: {
a: '^1.0.0',
},
},
'node_modules/a': {
version: '1.2.3',
resolved: 'https://dummy.npmjs.org/a/-/a-1.2.3.tgz',
integrity: 'sha512-dummy',
engines: {
node: '>=14.17',
},
},
},
}),
},
})
await npm.exec('query', ['*'])
t.matchSnapshot(joinedOutput(), 'should return valid response with only lock info')
})
t.end()
})

0 comments on commit f239540

Please sign in to comment.