diff --git a/docs/lib/check-nav.js b/docs/lib/check-nav.js index ac2c01038f438..0f9b3529c7546 100644 --- a/docs/lib/check-nav.js +++ b/docs/lib/check-nav.js @@ -29,17 +29,17 @@ function ensureNavigationComplete (nav, fsPaths, ext) { const errors = [] if (missingNav.length) { - errors.push('The following path(s) exist on disk but are not present in nav.yml:') + errors.push('The following path(s) exist on disk but are not present in /lib/content/nav.yml:') errors.push(...missingNav.map(n => ` ${n}`)) } if (missingFs.length) { - errors.push('The following path(s) exist in nav.yml but are not present on disk:') + errors.push('The following path(s) exist in lib/content/nav.yml but are not present on disk:') errors.push(...missingFs.map(n => ` ${n}`)) } if (errors.length) { - errors.unshift('Documentation navigation (nav.yml) does not match filesystem.') + errors.unshift('Documentation navigation (lib/content/nav.yml) does not match filesystem.') errors.push('Update nav.yml to ensure that all files are listed in the appropriate place.') throw new Error(errors.join('\n')) } diff --git a/docs/lib/content/commands/npm-undeprecate.md b/docs/lib/content/commands/npm-undeprecate.md new file mode 100644 index 0000000000000..076ac9eff2d0a --- /dev/null +++ b/docs/lib/content/commands/npm-undeprecate.md @@ -0,0 +1,24 @@ +--- +title: npm-undeprecate +section: 1 +description: Undeprecate a version of a package +--- + +### Synopsis + + + +### Description + +This command will update the npm registry entry for a package, removing any +deprecation warnings that currently exist. + +It works in the same way as [npm deprecate](/commands/npm-deprecate), except +that this command removes deprecation warnings instead of adding them. + +### Configuration + + +### See Also + +* [npm deprecate](/commands/npm-deprecate) diff --git a/docs/lib/content/nav.yml b/docs/lib/content/nav.yml index 96c89e5cc1b71..4148c4533efcb 100644 --- a/docs/lib/content/nav.yml +++ b/docs/lib/content/nav.yml @@ -177,6 +177,9 @@ - title: npm token url: /commands/npm-token description: Manage your authentication tokens + - title: npm undeprecate + url: /commands/npm-undeprecate + description: Undeprecate a version of a package - title: npm uninstall url: /commands/npm-uninstall description: Remove a package diff --git a/lib/commands/undeprecate.js b/lib/commands/undeprecate.js new file mode 100644 index 0000000000000..79ce66bbe5600 --- /dev/null +++ b/lib/commands/undeprecate.js @@ -0,0 +1,13 @@ +const Deprecate = require('./deprecate.js') + +class Undeprecate extends Deprecate { + static description = 'Undeprecate a version of a package' + static name = 'undeprecate' + static usage = [''] + + async exec ([pkg]) { + return super.exec([pkg, '']) + } +} + +module.exports = Undeprecate diff --git a/lib/utils/cmd-list.js b/lib/utils/cmd-list.js index 039d6ffddeb16..96eb0974a2ed3 100644 --- a/lib/utils/cmd-list.js +++ b/lib/utils/cmd-list.js @@ -62,6 +62,7 @@ const commands = [ 'team', 'test', 'token', + 'undeprecate', 'uninstall', 'unpublish', 'unstar', diff --git a/smoke-tests/tap-snapshots/test/index.js.test.cjs b/smoke-tests/tap-snapshots/test/index.js.test.cjs index 1de04263b4942..c04e01166f7cb 100644 --- a/smoke-tests/tap-snapshots/test/index.js.test.cjs +++ b/smoke-tests/tap-snapshots/test/index.js.test.cjs @@ -29,7 +29,8 @@ All commands: ping, pkg, prefix, profile, prune, publish, query, rebuild, repo, restart, root, run-script, sbom, search, set, shrinkwrap, star, stars, start, stop, team, test, token, - uninstall, unpublish, unstar, update, version, view, whoami + undeprecate, uninstall, unpublish, unstar, update, version, + view, whoami Specify configs in the ini-formatted file: {NPM}/{TESTDIR}/home/.npmrc diff --git a/tap-snapshots/test/lib/commands/completion.js.test.cjs b/tap-snapshots/test/lib/commands/completion.js.test.cjs index 9b6f1ba51c787..a281883539f61 100644 --- a/tap-snapshots/test/lib/commands/completion.js.test.cjs +++ b/tap-snapshots/test/lib/commands/completion.js.test.cjs @@ -100,6 +100,7 @@ Array [ team test token + undeprecate uninstall unpublish unstar diff --git a/tap-snapshots/test/lib/commands/publish.js.test.cjs b/tap-snapshots/test/lib/commands/publish.js.test.cjs index c0dc06b568180..1599f1dd5c394 100644 --- a/tap-snapshots/test/lib/commands/publish.js.test.cjs +++ b/tap-snapshots/test/lib/commands/publish.js.test.cjs @@ -208,6 +208,7 @@ Object { "man/man1/npm-team.1", "man/man1/npm-test.1", "man/man1/npm-token.1", + "man/man1/npm-undeprecate.1", "man/man1/npm-uninstall.1", "man/man1/npm-unpublish.1", "man/man1/npm-unstar.1", diff --git a/tap-snapshots/test/lib/docs.js.test.cjs b/tap-snapshots/test/lib/docs.js.test.cjs index 0ebee0d7ae896..baceb5dcd3e3c 100644 --- a/tap-snapshots/test/lib/docs.js.test.cjs +++ b/tap-snapshots/test/lib/docs.js.test.cjs @@ -155,6 +155,7 @@ Array [ "team", "test", "token", + "undeprecate", "uninstall", "unpublish", "unstar", @@ -2850,7 +2851,7 @@ Usage: npm deprecate Options: -[--registry ] [--otp ] +[--registry ] [--otp ] [--dry-run] Run "npm help deprecate" for more info @@ -2862,6 +2863,7 @@ Note: This command is unaware of workspaces. #### \`registry\` #### \`otp\` +#### \`dry-run\` ` exports[`test/lib/docs.js TAP usage diff > must match snapshot 1`] = ` @@ -4274,6 +4276,28 @@ Note: This command is unaware of workspaces. #### \`otp\` ` +exports[`test/lib/docs.js TAP usage undeprecate > must match snapshot 1`] = ` +Undeprecate a version of a package + +Usage: +npm undeprecate + +Options: +[--registry ] [--otp ] [--dry-run] + +Run "npm help undeprecate" for more info + +\`\`\`bash +npm undeprecate +\`\`\` + +Note: This command is unaware of workspaces. + +#### \`registry\` +#### \`otp\` +#### \`dry-run\` +` + exports[`test/lib/docs.js TAP usage uninstall > must match snapshot 1`] = ` Remove a package diff --git a/tap-snapshots/test/lib/npm.js.test.cjs b/tap-snapshots/test/lib/npm.js.test.cjs index 0864ffe37d297..88597c2fd15f6 100644 --- a/tap-snapshots/test/lib/npm.js.test.cjs +++ b/tap-snapshots/test/lib/npm.js.test.cjs @@ -39,7 +39,8 @@ All commands: ping, pkg, prefix, profile, prune, publish, query, rebuild, repo, restart, root, run-script, sbom, search, set, shrinkwrap, star, stars, start, stop, team, test, token, - uninstall, unpublish, unstar, update, version, view, whoami + undeprecate, uninstall, unpublish, unstar, update, version, + view, whoami Specify configs in the ini-formatted file: {USERCONFIG} @@ -89,9 +90,10 @@ All commands: search, set, shrinkwrap, star, stars, start, stop, team, test, token, - uninstall, unpublish, - unstar, update, version, - view, whoami + undeprecate, uninstall, + unpublish, unstar, + update, version, view, + whoami Specify configs in the ini-formatted file: {USERCONFIG} @@ -141,9 +143,10 @@ All commands: search, set, shrinkwrap, star, stars, start, stop, team, test, token, - uninstall, unpublish, - unstar, update, version, - view, whoami + undeprecate, uninstall, + unpublish, unstar, + update, version, view, + whoami Specify configs in the ini-formatted file: {USERCONFIG} @@ -179,7 +182,8 @@ All commands: ping, pkg, prefix, profile, prune, publish, query, rebuild, repo, restart, root, run-script, sbom, search, set, shrinkwrap, star, stars, start, stop, team, test, token, - uninstall, unpublish, unstar, update, version, view, whoami + undeprecate, uninstall, unpublish, unstar, update, version, + view, whoami Specify configs in the ini-formatted file: {USERCONFIG} @@ -229,9 +233,10 @@ All commands: search, set, shrinkwrap, star, stars, start, stop, team, test, token, - uninstall, unpublish, - unstar, update, version, - view, whoami + undeprecate, uninstall, + unpublish, unstar, + update, version, view, + whoami Specify configs in the ini-formatted file: {USERCONFIG} @@ -281,9 +286,10 @@ All commands: search, set, shrinkwrap, star, stars, start, stop, team, test, token, - uninstall, unpublish, - unstar, update, version, - view, whoami + undeprecate, uninstall, + unpublish, unstar, + update, version, view, + whoami Specify configs in the ini-formatted file: {USERCONFIG} @@ -331,10 +337,10 @@ All commands: run-script, sbom, search, set, shrinkwrap, star, stars, start, stop, team, - test, token, uninstall, - unpublish, unstar, - update, version, view, - whoami + test, token, undeprecate, + uninstall, unpublish, + unstar, update, version, + view, whoami Specify configs in the ini-formatted file: {USERCONFIG} @@ -370,8 +376,8 @@ All commands: ping, pkg, prefix, profile, prune, publish, query, rebuild, repo, restart, root, run-script, sbom, search, set, shrinkwrap, star, stars, start, stop, team, test, token, - uninstall, unpublish, unstar, update, version, view, - whoami + undeprecate, uninstall, unpublish, unstar, update, version, + view, whoami Specify configs in the ini-formatted file: {USERCONFIG} @@ -407,7 +413,8 @@ All commands: ping, pkg, prefix, profile, prune, publish, query, rebuild, repo, restart, root, run-script, sbom, search, set, shrinkwrap, star, stars, start, stop, team, test, token, - uninstall, unpublish, unstar, update, version, view, whoami + undeprecate, uninstall, unpublish, unstar, update, version, + view, whoami Specify configs in the ini-formatted file: {USERCONFIG} @@ -443,7 +450,8 @@ All commands: ping, pkg, prefix, profile, prune, publish, query, rebuild, repo, restart, root, run-script, sbom, search, set, shrinkwrap, star, stars, start, stop, team, test, token, - uninstall, unpublish, unstar, update, version, view, whoami + undeprecate, uninstall, unpublish, unstar, update, version, + view, whoami Specify configs in the ini-formatted file: {USERCONFIG} diff --git a/test/lib/commands/undeprecate.js b/test/lib/commands/undeprecate.js new file mode 100644 index 0000000000000..775a2183a1299 --- /dev/null +++ b/test/lib/commands/undeprecate.js @@ -0,0 +1,72 @@ +const t = require('tap') +const { load: loadMockNpm } = require('../../fixtures/mock-npm') + +const MockRegistry = require('@npmcli/mock-registry') + +const token = 'test-auth-token' +const auth = { '//registry.npmjs.org/:_authToken': token } +const versions = ['1.0.0', '1.0.1', '1.0.1-pre'] + +t.test('no args', async t => { + const { npm } = await loadMockNpm(t) + await t.rejects( + npm.exec('undeprecate', []), + { code: 'EUSAGE' }, + 'logs usage' + ) +}) + +t.test('undeprecate', async t => { + const { npm, logs, joinedOutput } = await loadMockNpm(t, { config: { ...auth } }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: token, + }) + const manifest = registry.manifest({ + name: 'foo', + versions, + }) + await registry.package({ manifest, query: { write: true } }) + registry.nock.put('/foo', body => { + for (const version of versions) { + if (body.versions[version].deprecated !== '') { + return false + } + } + return true + }).reply(200, {}) + + await npm.exec('undeprecate', ['foo']) + t.match(logs.notice, [ + 'undeprecating foo@1.0.0', + 'undeprecating foo@1.0.1', + 'undeprecating foo@1.0.1-pre', + ]) + t.match(joinedOutput(), '') +}) + +t.test('dry-run', async t => { + const { npm, logs, joinedOutput } = await loadMockNpm(t, { config: { + 'dry-run': true, + ...auth, + } }) + const registry = new MockRegistry({ + tap: t, + registry: npm.config.get('registry'), + authorization: token, + }) + const manifest = registry.manifest({ + name: 'foo', + versions, + }) + await registry.package({ manifest, query: { write: true } }) + + await npm.exec('undeprecate', ['foo']) + t.match(logs.notice, [ + 'undeprecating foo@1.0.0', + 'undeprecating foo@1.0.1', + 'undeprecating foo@1.0.1-pre', + ]) + t.match(joinedOutput(), '') +})