diff --git a/lib/utils/key-values.js b/lib/utils/key-values.js index cf54304da6b4b..ec9f409893115 100644 --- a/lib/utils/key-values.js +++ b/lib/utils/key-values.js @@ -26,11 +26,23 @@ function logObject (values, { chalk, json, predicate = defaultPredicate }) { } function logStageItem (item, { chalk }) { - const { id, packageName, version, tag, createdAt, actor, actorType, shasum, ...rest } = item + const { + id, + packageName, + version, + tag, + createdAt, + actor, + actorType, + shasum, + status, + ...rest + } = item logObject({ id, 'package name': packageName, version, + status, tag, 'date staged': createdAt, 'staged by': actorType ? `${actor} (${actorType})` : actor, diff --git a/test/lib/commands/stage/list.js b/test/lib/commands/stage/list.js index e66680db8277f..ded079a5ab7b0 100644 --- a/test/lib/commands/stage/list.js +++ b/test/lib/commands/stage/list.js @@ -15,6 +15,7 @@ const stageItems = [ actor: 'octocat', actorType: 'user', shasum: '4f7f5f1d5bcf2f72f6e4d6c4f3b2812d8a2f6c19', + status: 'validating', }, { id: 'f8e7a45b-7a5f-4f31-8e6d-9dd1c6ef38c0', @@ -25,6 +26,7 @@ const stageItems = [ actor: 'npm-bot', actorType: 'trusted automation', shasum: '8eb3b4e9b6e3d0d2c86be1e6d4f43f4be62e80ad', + status: 'staged', }, ] @@ -45,6 +47,9 @@ t.test('lists all staged packages', async t => { t.match(out, 'package name: example-lib') t.match(out, 'version: 1.2.3') t.match(out, 'version: 0.4.0') + t.match(out, 'status: validating') + t.match(out, 'status: staged') + t.equal(out.match(/status:/g)?.length, 2, 'all server-provided statuses are shown') }) t.test('lists with package filter', async t => { @@ -80,6 +85,8 @@ t.test('lists with --json', async t => { t.equal(out.length, 2) t.equal(out[0].packageName, '@npmcli/example-package') t.equal(out[0].id, '1de6f3db-2ed9-4d72-b3dd-8f0e2b474a2f', 'uuid id is not redacted') + t.equal(out[0].status, 'validating') + t.equal(out[1].status, 'staged') }) t.test('shows message when no packages', async t => { diff --git a/test/lib/commands/stage/view.js b/test/lib/commands/stage/view.js index 604caf98fb23b..36afc98b13d71 100644 --- a/test/lib/commands/stage/view.js +++ b/test/lib/commands/stage/view.js @@ -14,6 +14,7 @@ const stageItem = { actor: 'octocat', actorType: 'user', shasum: '4f7f5f1d5bcf2f72f6e4d6c4f3b2812d8a2f6c19', + status: 'awaiting_approval', } t.test('views a staged package', async t => { @@ -31,6 +32,7 @@ t.test('views a staged package', async t => { t.match(out, /id:/) t.match(out, 'package name: @npmcli/example-package') t.match(out, 'version: 1.2.3') + t.match(out, 'status: awaiting_approval') }) t.test('views with --json', async t => { @@ -47,6 +49,7 @@ t.test('views with --json', async t => { const out = JSON.parse(joinedOutput()) t.ok(out.id) t.equal(out.packageName, '@npmcli/example-package') + t.equal(out.status, 'awaiting_approval') }) t.test('throws usageError without stage-id', async t => { diff --git a/test/lib/utils/key-values.js b/test/lib/utils/key-values.js index 5e61f9e55fe59..f162346eab4b2 100644 --- a/test/lib/utils/key-values.js +++ b/test/lib/utils/key-values.js @@ -76,6 +76,40 @@ t.test('logStageItem without actorType shows actor alone', async t => { t.notMatch(out, /\(/) }) +t.test('logStageItem shows status returned by the server', async t => { + const { joinedOutput } = await loadMockNpm(t) + const chalk = { cyan: v => v, green: v => v } + const item = { + id: 'abc', + packageName: 'pkg', + version: '1.0.0', + tag: 'latest', + createdAt: '2026-01-01', + actor: 'user', + shasum: 'sha1', + } + + logStageItem({ ...item, status: 'awaiting_approval' }, { chalk }) + t.match(joinedOutput(), /status: awaiting_approval/) +}) + +t.test('logStageItem omits missing status', async t => { + const { joinedOutput } = await loadMockNpm(t) + const chalk = { cyan: v => v, green: v => v } + const item = { + id: 'abc', + packageName: 'pkg', + version: '1.0.0', + tag: 'latest', + createdAt: '2026-01-01', + actor: 'user', + shasum: 'sha1', + } + + logStageItem(item, { chalk }) + t.notMatch(joinedOutput(), /status:/) +}) + t.test('logObject with all values skipped produces no output', async t => { const { joinedOutput } = await loadMockNpm(t) const chalk = { cyan: v => v, green: v => v }