diff --git a/lib/utils/queryable.js b/lib/utils/queryable.js index fac7581e6f852..00a8b55389ab6 100644 --- a/lib/utils/queryable.js +++ b/lib/utils/queryable.js @@ -94,12 +94,12 @@ const getter = ({ data, key }, { unwrapSingleItemArrays = true } = {}) => { const maybeIndex = Number(k) if (Array.isArray(_data) && !Number.isInteger(maybeIndex)) { _data = _data.reduce((acc, i, index) => { - acc[`${label}[${index}].${k}`] = i[k] + acc[`${label}[${index}].${k}`] = i?.[k] return acc }, {}) return _data } else { - if (!Object.hasOwn(_data, k)) { + if (_data == null || !Object.hasOwn(_data, k)) { return undefined } _data = _data[k] diff --git a/test/lib/commands/pkg.js b/test/lib/commands/pkg.js index 50288cc42366b..c539726ee1da3 100644 --- a/test/lib/commands/pkg.js +++ b/test/lib/commands/pkg.js @@ -164,6 +164,22 @@ t.test('get', t => { ) }) + t.test('nested arg below a null value', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { + prefixDir: { + 'package.json': JSON.stringify({ + name: 'foo', + config: { optional: null }, + }), + }, + config: { json: true }, + }) + + await npm.exec('pkg', ['get', 'config.optional.enabled', 'config.optional']) + + t.strictSame(JSON.parse(joinedOutput()), { 'config.optional': null }) + }) + t.test('array field', async t => { const { npm, joinedOutput } = await loadMockNpm(t, { prefixDir: { @@ -274,6 +290,25 @@ t.test('get', t => { 'should print json result containing matching results' ) }) + + t.test('get array nested items with a null entry', async t => { + const { npm, joinedOutput } = await loadMockNpm(t, { + prefixDir: { + 'package.json': JSON.stringify({ + name: 'foo', + targets: [{ name: 'first' }, null, { name: 'third' }], + }), + }, + config: { json: true }, + }) + + await npm.exec('pkg', ['get', 'targets.name']) + + t.strictSame(JSON.parse(joinedOutput()), { + 'targets[0].name': 'first', + 'targets[2].name': 'third', + }) + }) t.end() })