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 Sep 11, 2023
1 parent 0d29855 commit 81a460f
Show file tree
Hide file tree
Showing 5 changed files with 128 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).

### Package lock only mode

Expand Down
15 changes: 14 additions & 1 deletion lib/commands/query.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

const { resolve } = require('path')
const BaseCommand = require('../base-command.js')
const log = require('../utils/log-shim.js')

class QuerySelectorItem {
constructor (node) {
Expand Down Expand Up @@ -48,6 +49,7 @@ class Query extends BaseCommand {
'workspace',
'workspaces',
'include-workspace-root',
'package-lock-only',
]

get parsedResponse () {
Expand All @@ -64,7 +66,18 @@ 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) {
log.verbose('loadVirtual', err.stack)
/* 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 @@ -3797,7 +3797,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 @@ -3809,6 +3809,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 81a460f

Please sign in to comment.