Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/npm/cli.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGar <gar+gh@danger.computer>2022-08-31 18:37:26 +0300
committerNathan Fritz <fritzy@github.com>2022-09-15 02:08:53 +0300
commit9c32c6c8d6fc5bdfd6af685731fe26920d7e5446 (patch)
treeae380e4350d71ce22d54e11f993c13727be3f408
parent854521baa49ef88ff9586ec2cc5f1fbaee7fa364 (diff)
feat(rewrite): rewrite `npm access`
BREAKING CHANGE: renames most of the `npm access` subcommands - `edit`, having never been implemented, is removed - `public` is now `set status=public` - `restricted` is now `set status=private` - `ls-packages` is now `list packages` - `ls-collaborators` is now `list collaborators` - `2fa-required` is now `set mfa=publish` - `2fa-not-required` is now `set mfa=none` - `set mfa=automation` is added - output is no longer in json by default Usage: npm access list packages [<user>|<scope>|<scope:team> [<package>] npm access list collaborators [<package> [<user>]] npm access get status [<package>] npm access set status=public|private [<package>] npm access set mfa=false|publish|automation [<package>] npm access grant <read-only|read-write> <scope:team> [<package>] npm access revoke <scope:team> [<package>] Options: [--json] [--otp <otp>] [--registry <registry>]
-rw-r--r--docs/content/commands/npm-access.md35
-rw-r--r--lib/commands/access.js284
-rw-r--r--lib/commands/deprecate.js4
-rw-r--r--lib/commands/unpublish.js4
-rw-r--r--tap-snapshots/test/lib/commands/completion.js.test.cjs16
-rw-r--r--tap-snapshots/test/lib/load-all-commands.js.test.cjs14
-rw-r--r--tap-snapshots/test/lib/npm.js.test.cjs14
-rw-r--r--test/fixtures/mock-registry.js39
-rw-r--r--test/lib/commands/access.js659
-rw-r--r--test/lib/commands/deprecate.js9
-rw-r--r--test/lib/commands/unpublish.js43
11 files changed, 517 insertions, 604 deletions
diff --git a/docs/content/commands/npm-access.md b/docs/content/commands/npm-access.md
index f7a98af65..bc481eac1 100644
--- a/docs/content/commands/npm-access.md
+++ b/docs/content/commands/npm-access.md
@@ -11,15 +11,13 @@ description: Set access level on published packages
<!-- see lib/commands/access.js -->
```bash
-npm access public [<package>]
-npm access restricted [<package>]
+npm access list packages [<user>|<scope>|<scope:team> [<package>]
+npm access list collaborators [<package> [<user>]]
+npm access get status [<package>]
+npm access set status=public|private [<package>]
+npm access set mfa=none|publish|automation [<package>]
npm access grant <read-only|read-write> <scope:team> [<package>]
npm access revoke <scope:team> [<package>]
-npm access 2fa-required [<package>]
-npm access 2fa-not-required [<package>]
-npm access ls-packages [<user>|<scope>|<scope:team>]
-npm access ls-collaborators [<package> [<user>]]
-npm access edit [<package>]
```
<!-- automatically generated, do not edit manually -->
@@ -91,12 +89,17 @@ Management of teams and team memberships is done with the `npm team` command.
<!-- AUTOGENERATED CONFIG DESCRIPTIONS START -->
<!-- automatically generated, do not edit manually -->
<!-- see lib/utils/config/definitions.js -->
-#### `registry`
+#### `json`
-* Default: "https://registry.npmjs.org/"
-* Type: URL
+* Default: false
+* Type: Boolean
-The base URL of the npm registry.
+Whether or not to output JSON data, rather than the normal output.
+
+* In `npm pkg set` it enables parsing set values with JSON.parse() before
+ saving them to your `package.json`.
+
+Not supported by all npm commands.
<!-- automatically generated, do not edit manually -->
<!-- see lib/utils/config/definitions.js -->
@@ -115,6 +118,16 @@ password, npm will prompt on the command line for one.
<!-- automatically generated, do not edit manually -->
<!-- see lib/utils/config/definitions.js -->
+#### `registry`
+
+* Default: "https://registry.npmjs.org/"
+* Type: URL
+
+The base URL of the npm registry.
+
+<!-- automatically generated, do not edit manually -->
+<!-- see lib/utils/config/definitions.js -->
+
<!-- AUTOGENERATED CONFIG DESCRIPTIONS END -->
### See Also
diff --git a/lib/commands/access.js b/lib/commands/access.js
index 362186153..d5ac5bb2f 100644
--- a/lib/commands/access.js
+++ b/lib/commands/access.js
@@ -1,223 +1,221 @@
const path = require('path')
-const libaccess = require('libnpmaccess')
+const libnpmaccess = require('libnpmaccess')
+const npa = require('npm-package-arg')
const readPackageJson = require('read-package-json-fast')
+const localeCompare = require('@isaacs/string-locale-compare')('en')
const otplease = require('../utils/otplease.js')
const getIdentity = require('../utils/get-identity.js')
-const log = require('../utils/log-shim.js')
const BaseCommand = require('../base-command.js')
-const subcommands = [
- 'public',
- 'restricted',
+const commands = [
+ 'get',
'grant',
+ 'list',
'revoke',
- 'ls-packages',
- 'ls-collaborators',
- 'edit',
- '2fa-required',
- '2fa-not-required',
+ 'set',
]
-const deprecated = [
- '2fa-not-required',
- '2fa-required',
- 'ls-collaborators',
- 'ls-packages',
- 'public',
- 'restricted',
+const setCommands = [
+ 'status=public',
+ 'status=private',
+ 'mfa=none',
+ 'mfa=publish',
+ 'mfa=automation',
+ '2fa=none',
+ '2fa=publish',
+ '2fa=automation',
]
class Access extends BaseCommand {
static description = 'Set access level on published packages'
static name = 'access'
static params = [
- 'registry',
+ 'json',
'otp',
+ 'registry',
]
static ignoreImplicitWorkspace = true
static usage = [
- 'public [<package>]',
- 'restricted [<package>]',
+ 'list packages [<user>|<scope>|<scope:team> [<package>]',
+ 'list collaborators [<package> [<user>]]',
+ 'get status [<package>]',
+ 'set status=public|private [<package>]',
+ 'set mfa=none|publish|automation [<package>]',
'grant <read-only|read-write> <scope:team> [<package>]',
'revoke <scope:team> [<package>]',
- '2fa-required [<package>]',
- '2fa-not-required [<package>]',
- 'ls-packages [<user>|<scope>|<scope:team>]',
- 'ls-collaborators [<package> [<user>]]',
- 'edit [<package>]',
]
async completion (opts) {
const argv = opts.conf.argv.remain
if (argv.length === 2) {
- return subcommands
+ return commands
}
switch (argv[2]) {
case 'grant':
- if (argv.length === 3) {
- return ['read-only', 'read-write']
- } else {
- return []
- }
-
- case 'public':
- case 'restricted':
- case 'ls-packages':
- case 'ls-collaborators':
- case 'edit':
- case '2fa-required':
- case '2fa-not-required':
+ return ['read-only', 'read-write']
case 'revoke':
return []
+ case 'list':
+ case 'ls':
+ return ['packages', 'collaborators']
+ case 'get':
+ return ['status']
+ case 'set':
+ return setCommands
default:
throw new Error(argv[2] + ' not recognized')
}
}
- async exec ([cmd, ...args]) {
+ async exec ([cmd, subcmd, ...args]) {
if (!cmd) {
- throw this.usageError('Subcommand is required.')
+ throw this.usageError()
}
-
- if (!subcommands.includes(cmd) || !this[cmd]) {
- throw this.usageError(`${cmd} is not a recognized subcommand.`)
+ if (!commands.includes(cmd)) {
+ throw this.usageError(`${cmd} is not a valid access command`)
}
-
- if (deprecated.includes(cmd)) {
- log.warn('access', `${cmd} subcommand will be removed in the next version of npm`)
+ // All commands take at least one more parameter so we can do this check up front
+ if (!subcmd) {
+ throw this.usageError()
}
- return this[cmd](args, {
- ...this.npm.flatOptions,
- })
- }
-
- public ([pkg], opts) {
- return this.modifyPackage(pkg, opts, libaccess.public)
- }
-
- restricted ([pkg], opts) {
- return this.modifyPackage(pkg, opts, libaccess.restricted)
- }
-
- async grant ([perms, scopeteam, pkg], opts) {
- if (!perms || (perms !== 'read-only' && perms !== 'read-write')) {
- throw this.usageError('First argument must be either `read-only` or `read-write`.')
- }
-
- if (!scopeteam) {
- throw this.usageError('`<scope:team>` argument is required.')
- }
-
- const [, scope, team] = scopeteam.match(/^@?([^:]+):(.*)$/) || []
-
- if (!scope && !team) {
- throw this.usageError(
- 'Second argument used incorrect format.\n' +
- 'Example: @example:developers'
- )
- }
-
- return this.modifyPackage(pkg, opts, (pkgName, opts) =>
- libaccess.grant(pkgName, scopeteam, perms, opts), false)
- }
-
- async revoke ([scopeteam, pkg], opts) {
- if (!scopeteam) {
- throw this.usageError('`<scope:team>` argument is required.')
- }
-
- const [, scope, team] = scopeteam.match(/^@?([^:]+):(.*)$/) || []
-
- if (!scope || !team) {
- throw this.usageError(
- 'First argument used incorrect format.\n' +
- 'Example: @example:developers'
- )
+ switch (cmd) {
+ case 'grant':
+ if (!['read-only', 'read-write'].includes(subcmd)) {
+ throw this.usageError('grant must be either `read-only` or `read-write`')
+ }
+ if (!args[0]) {
+ throw this.usageError('`<scope:team>` argument is required')
+ }
+ return this.#grant(subcmd, args[0], args[1])
+ case 'revoke':
+ return this.#revoke(subcmd, args[0])
+ case 'list':
+ case 'ls':
+ if (subcmd === 'packages') {
+ return this.#listPackages(args[0], args[1])
+ }
+ if (subcmd === 'collaborators') {
+ return this.#listCollaborators(args[0], args[1])
+ }
+ throw this.usageError(`list ${subcmd} is not a valid access command`)
+ case 'get':
+ if (subcmd !== 'status') {
+ throw this.usageError(`get ${subcmd} is not a valid access command`)
+ }
+ return this.#getStatus(args[0])
+ case 'set':
+ if (!setCommands.includes(subcmd)) {
+ throw this.usageError(`set ${subcmd} is not a valid access command`)
+ }
+ return this.#set(subcmd, args[0])
}
-
- return this.modifyPackage(pkg, opts, (pkgName, opts) =>
- libaccess.revoke(pkgName, scopeteam, opts))
- }
-
- get ['2fa-required'] () {
- return this.tfaRequired
- }
-
- tfaRequired ([pkg], opts) {
- return this.modifyPackage(pkg, opts, libaccess.tfaRequired, false)
}
- get ['2fa-not-required'] () {
- return this.tfaNotRequired
+ async #grant (permissions, scope, pkg) {
+ await libnpmaccess.setPermissions(scope, pkg, permissions)
}
- tfaNotRequired ([pkg], opts) {
- return this.modifyPackage(pkg, opts, libaccess.tfaNotRequired, false)
+ async #revoke (scope, pkg) {
+ await libnpmaccess.removePermissions(scope, pkg)
}
- get ['ls-packages'] () {
- return this.lsPackages
- }
-
- async lsPackages ([owner], opts) {
+ async #listPackages (owner, pkg) {
if (!owner) {
- owner = await getIdentity(this.npm, opts)
+ owner = await getIdentity(this.npm, this.npm.flatOptions)
}
-
- const pkgs = await libaccess.lsPackages(owner, opts)
-
- // TODO - print these out nicely (breaking change)
- this.npm.output(JSON.stringify(pkgs, null, 2))
+ const pkgs = await libnpmaccess.getPackages(owner, this.npm.flatOptions)
+ this.#output(pkgs, pkg)
}
- get ['ls-collaborators'] () {
- return this.lsCollaborators
+ async #listCollaborators (pkg, user) {
+ const pkgName = await this.#getPackage(pkg, false)
+ const collabs = await libnpmaccess.getCollaborators(pkgName, this.npm.flatOptions)
+ this.#output(collabs, user)
}
- async lsCollaborators ([pkg, usr], opts) {
- const pkgName = await this.getPackage(pkg, false)
- const collabs = await libaccess.lsCollaborators(pkgName, usr, opts)
+ async #getStatus (pkg) {
+ const pkgName = await this.#getPackage(pkg, false)
+ const visibility = await libnpmaccess.getVisibility(pkgName, this.npm.flatOptions)
+ this.#output({ [pkgName]: visibility.public ? 'public' : 'private' })
+ }
- // TODO - print these out nicely (breaking change)
- this.npm.output(JSON.stringify(collabs, null, 2))
+ async #set (subcmd, pkg) {
+ const [subkey, subval] = subcmd.split('=')
+ switch (subkey) {
+ case 'mfa':
+ case '2fa':
+ return this.#setMfa(pkg, subval)
+ case 'status':
+ return this.#setStatus(pkg, subval)
+ }
}
- async edit () {
- throw new Error('edit subcommand is not implemented')
+ async #setMfa (pkg, level) {
+ const pkgName = await this.#getPackage(pkg, false)
+ await otplease(this.npm, this.npm.flatOptions, (opts) => {
+ return libnpmaccess.setMfa(pkgName, level, opts)
+ })
}
- modifyPackage (pkg, opts, fn, requireScope = true) {
- return this.getPackage(pkg, requireScope)
- .then(pkgName => otplease(this.npm, opts, opts => fn(pkgName, opts)))
+ async #setStatus (pkg, status) {
+ // only scoped packages can have their access changed
+ const pkgName = await this.#getPackage(pkg, true)
+ if (status === 'private') {
+ status = 'restricted'
+ }
+ await otplease(this.npm, this.npm.flatOptions, (opts) => {
+ return libnpmaccess.setAccess(pkgName, status, opts)
+ })
+ return this.#getStatus(pkgName)
}
- async getPackage (name, requireScope) {
- if (name && name.trim()) {
- return name.trim()
- } else {
+ async #getPackage (name, requireScope) {
+ if (!name) {
try {
const pkg = await readPackageJson(path.resolve(this.npm.prefix, 'package.json'))
name = pkg.name
} catch (err) {
if (err.code === 'ENOENT') {
- throw new Error(
- 'no package name passed to command and no package.json found'
- )
+ throw Object.assign(new Error('no package name given and no package.json found'), {
+ code: 'ENOENT',
+ })
} else {
throw err
}
}
+ }
- if (requireScope && !name.match(/^@[^/]+\/.*$/)) {
- throw this.usageError('This command is only available for scoped packages.')
- } else {
- return name
+ const spec = npa(name)
+ if (requireScope && !spec.scope) {
+ throw this.usageError('This command is only available for scoped packages.')
+ }
+ return name
+ }
+
+ #output (items, limiter) {
+ const output = {}
+ const lookup = {
+ __proto__: null,
+ read: 'read-only',
+ write: 'read-write',
+ }
+ for (const item in items) {
+ const val = items[item]
+ output[item] = lookup[val] || val
+ }
+ if (this.npm.config.get('json')) {
+ this.npm.output(JSON.stringify(output, null, 2))
+ } else {
+ for (const item of Object.keys(output).sort(localeCompare)) {
+ if (!limiter || limiter === item) {
+ this.npm.output(`${item}: ${output[item]}`)
+ }
}
}
}
diff --git a/lib/commands/deprecate.js b/lib/commands/deprecate.js
index 068bfdbce..c41546eb1 100644
--- a/lib/commands/deprecate.js
+++ b/lib/commands/deprecate.js
@@ -23,10 +23,10 @@ class Deprecate extends BaseCommand {
}
const username = await getIdentity(this.npm, this.npm.flatOptions)
- const packages = await libaccess.lsPackages(username, this.npm.flatOptions)
+ const packages = await libaccess.getPackages(username, this.npm.flatOptions)
return Object.keys(packages)
.filter((name) =>
- packages[name] === 'read-write' &&
+ packages[name] === 'write' &&
(opts.conf.argv.remain.length === 0 ||
name.startsWith(opts.conf.argv.remain[0])))
}
diff --git a/lib/commands/unpublish.js b/lib/commands/unpublish.js
index 0e5ef3dc5..968bcf801 100644
--- a/lib/commands/unpublish.js
+++ b/lib/commands/unpublish.js
@@ -42,11 +42,11 @@ class Unpublish extends BaseCommand {
return []
}
- const access = await libaccess.lsPackages(username, opts)
+ const access = await libaccess.getPackages(username, opts)
// do a bit of filtering at this point, so that we don't need
// to fetch versions for more than one thing, but also don't
// accidentally unpublish a whole project
- let pkgs = Object.keys(access || {})
+ let pkgs = Object.keys(access)
if (!partialWord || !pkgs.length) {
return pkgs
}
diff --git a/tap-snapshots/test/lib/commands/completion.js.test.cjs b/tap-snapshots/test/lib/commands/completion.js.test.cjs
index fb4c53a02..85a883bd5 100644
--- a/tap-snapshots/test/lib/commands/completion.js.test.cjs
+++ b/tap-snapshots/test/lib/commands/completion.js.test.cjs
@@ -172,11 +172,7 @@ Array [
`
exports[`test/lib/commands/completion.js TAP completion filtered subcommands > filtered subcommands 1`] = `
-Array [
- Array [
- "public",
- ],
-]
+Array []
`
exports[`test/lib/commands/completion.js TAP completion flags > flags 1`] = `
@@ -220,15 +216,11 @@ exports[`test/lib/commands/completion.js TAP completion subcommand completion >
Array [
Array [
String(
- public
- restricted
+ get
grant
+ list
revoke
- ls-packages
- ls-collaborators
- edit
- 2fa-required
- 2fa-not-required
+ set
),
],
]
diff --git a/tap-snapshots/test/lib/load-all-commands.js.test.cjs b/tap-snapshots/test/lib/load-all-commands.js.test.cjs
index d4a340431..038121be9 100644
--- a/tap-snapshots/test/lib/load-all-commands.js.test.cjs
+++ b/tap-snapshots/test/lib/load-all-commands.js.test.cjs
@@ -9,18 +9,16 @@ exports[`test/lib/load-all-commands.js TAP load each command access > must match
Set access level on published packages
Usage:
-npm access public [<package>]
-npm access restricted [<package>]
+npm access list packages [<user>|<scope>|<scope:team> [<package>]
+npm access list collaborators [<package> [<user>]]
+npm access get status [<package>]
+npm access set status=public|private [<package>]
+npm access set mfa=none|publish|automation [<package>]
npm access grant <read-only|read-write> <scope:team> [<package>]
npm access revoke <scope:team> [<package>]
-npm access 2fa-required [<package>]
-npm access 2fa-not-required [<package>]
-npm access ls-packages [<user>|<scope>|<scope:team>]
-npm access ls-collaborators [<package> [<user>]]
-npm access edit [<package>]
Options:
-[--registry <registry>] [--otp <otp>]
+[--json] [--otp <otp>] [--registry <registry>]
Run "npm help access" for more info
`
diff --git a/tap-snapshots/test/lib/npm.js.test.cjs b/tap-snapshots/test/lib/npm.js.test.cjs
index 68adb5551..1c3dbe39b 100644
--- a/tap-snapshots/test/lib/npm.js.test.cjs
+++ b/tap-snapshots/test/lib/npm.js.test.cjs
@@ -168,18 +168,16 @@ All commands:
access Set access level on published packages
Usage:
- npm access public [<package>]
- npm access restricted [<package>]
+ npm access list packages [<user>|<scope>|<scope:team> [<package>]
+ npm access list collaborators [<package> [<user>]]
+ npm access get status [<package>]
+ npm access set status=public|private [<package>]
+ npm access set mfa=none|publish|automation [<package>]
npm access grant <read-only|read-write> <scope:team> [<package>]
npm access revoke <scope:team> [<package>]
- npm access 2fa-required [<package>]
- npm access 2fa-not-required [<package>]
- npm access ls-packages [<user>|<scope>|<scope:team>]
- npm access ls-collaborators [<package> [<user>]]
- npm access edit [<package>]
Options:
- [--registry <registry>] [--otp <otp>]
+ [--json] [--otp <otp>] [--registry <registry>]
Run "npm help access" for more info
diff --git a/test/fixtures/mock-registry.js b/test/fixtures/mock-registry.js
index 8fb5a055f..65d475962 100644
--- a/test/fixtures/mock-registry.js
+++ b/test/fixtures/mock-registry.js
@@ -67,21 +67,19 @@ class MockRegistry {
}
}
- access ({ spec, access, publishRequires2fa }) {
- const body = {}
- if (access !== undefined) {
- body.access = access
- }
- if (publishRequires2fa !== undefined) {
- body.publish_requires_tfa = publishRequires2fa
- }
+ setAccess ({ spec, body = {} }) {
this.nock = this.nock.post(
- `/-/package/${encodeURIComponent(spec)}/access`,
+ `/-/package/${npa(spec).escapedName}/access`,
body
).reply(200)
}
- grant ({ spec, team, permissions }) {
+ getVisibility ({ spec, visibility }) {
+ this.nock = this.nock.get(`/-/package/${npa(spec).escapedName}/visibility`)
+ .reply(200, visibility)
+ }
+
+ setPermissions ({ spec, team, permissions }) {
if (team.startsWith('@')) {
team = team.slice(1)
}
@@ -92,7 +90,7 @@ class MockRegistry {
).reply(200)
}
- revoke ({ spec, team }) {
+ removePermissions ({ spec, team }) {
if (team.startsWith('@')) {
team = team.slice(1)
}
@@ -141,27 +139,22 @@ class MockRegistry {
}
// team can be a team or a username
- lsPackages ({ team, packages = {}, times = 1 }) {
+ getPackages ({ team, packages = {}, times = 1 }) {
if (team.startsWith('@')) {
team = team.slice(1)
}
- const [scope, teamName] = team.split(':')
+ const [scope, teamName] = team.split(':').map(encodeURIComponent)
let uri
if (teamName) {
- uri = `/-/team/${encodeURIComponent(scope)}/${encodeURIComponent(teamName)}/package`
+ uri = `/-/team/${scope}/${teamName}/package`
} else {
- uri = `/-/org/${encodeURIComponent(scope)}/package`
+ uri = `/-/org/${scope}/package`
}
- this.nock = this.nock.get(uri).query({ format: 'cli' }).times(times).reply(200, packages)
+ this.nock = this.nock.get(uri).times(times).reply(200, packages)
}
- lsCollaborators ({ spec, user, collaborators = {} }) {
- const query = { format: 'cli' }
- if (user) {
- query.user = user
- }
- this.nock = this.nock.get(`/-/package/${encodeURIComponent(spec)}/collaborators`)
- .query(query)
+ getCollaborators ({ spec, collaborators = {} }) {
+ this.nock = this.nock.get(`/-/package/${npa(spec).escapedName}/collaborators`)
.reply(200, collaborators)
}
diff --git a/test/lib/commands/access.js b/test/lib/commands/access.js
index aa748b106..ae26f4c93 100644
--- a/test/lib/commands/access.js
+++ b/test/lib/commands/access.js
@@ -3,6 +3,7 @@ const t = require('tap')
const { load: loadMockNpm } = require('../../fixtures/mock-npm.js')
const MockRegistry = require('../../fixtures/mock-registry.js')
+const token = 'test-auth-token'
const auth = { '//registry.npmjs.org/:_authToken': 'test-auth-token' }
t.test('completion', async t => {
@@ -13,20 +14,21 @@ t.test('completion', async t => {
t.resolves(res, expect, argv.join(' '))
}
- testComp(['npm', 'access'], [
- 'public', 'restricted', 'grant', 'revoke', 'ls-packages',
- 'ls-collaborators', 'edit', '2fa-required', '2fa-not-required',
+ testComp(['npm', 'access'], ['list', 'get', 'set', 'grant', 'revoke'])
+ testComp(['npm', 'access', 'list'], ['packages', 'collaborators'])
+ testComp(['npm', 'access', 'ls'], ['packages', 'collaborators'])
+ testComp(['npm', 'access', 'get'], ['status'])
+ testComp(['npm', 'access', 'set'], [
+ 'status=public',
+ 'status=private',
+ 'mfa=none',
+ 'mfa=publish',
+ 'mfa=automation',
+ '2fa=none',
+ '2fa=publish',
+ '2fa=automation',
])
testComp(['npm', 'access', 'grant'], ['read-only', 'read-write'])
- testComp(['npm', 'access', 'grant', 'read-only'], [])
- testComp(['npm', 'access', 'public'], [])
- testComp(['npm', 'access', 'restricted'], [])
- testComp(['npm', 'access', 'revoke'], [])
- testComp(['npm', 'access', 'ls-packages'], [])
- testComp(['npm', 'access', 'ls-collaborators'], [])
- testComp(['npm', 'access', 'edit'], [])
- testComp(['npm', 'access', '2fa-required'], [])
- testComp(['npm', 'access', '2fa-not-required'], [])
testComp(['npm', 'access', 'revoke'], [])
await t.rejects(
@@ -35,406 +37,337 @@ t.test('completion', async t => {
)
})
-t.test('subcommand required', async t => {
+t.test('command required', async t => {
const { npm } = await loadMockNpm(t)
- const access = await npm.cmd('access')
- await t.rejects(
- npm.exec('access', []),
- access.usageError('Subcommand is required.')
- )
+ await t.rejects(npm.exec('access', []), { code: 'EUSAGE' })
})
-t.test('unrecognized subcommand', async t => {
+t.test('unrecognized command', async t => {
const { npm } = await loadMockNpm(t)
await t.rejects(
- npm.exec('access', ['blerg']),
- /blerg is not a recognized subcommand/,
- 'should throw EUSAGE on missing subcommand'
- )
+ npm.exec('access', ['blerg']), { code: 'EUSAGE' })
})
-t.test('edit', async t => {
+t.test('subcommand required', async t => {
const { npm } = await loadMockNpm(t)
- await t.rejects(
- npm.exec('access', ['edit', '@scoped/another']),
- /edit subcommand is not implemented/,
- 'should throw not implemented yet error'
- )
+ await t.rejects(npm.exec('access', ['get']), { code: 'EUSAGE' })
})
-t.test('access public on unscoped package', async t => {
- const { npm } = await loadMockNpm(t, {
- prefixDir: {
- 'package.json': JSON.stringify({
- name: 'npm-access-public-pkg',
- }),
- },
- })
- await t.rejects(
- npm.exec('access', ['public']),
- /This command is only available for scoped packages/,
- 'should throw scoped-restricted error'
- )
+t.test('unrecognized subcommand', async t => {
+ const { npm } = await loadMockNpm(t)
+ await t.rejects(npm.exec('access', ['list', 'blerg']), { code: 'EUSAGE' })
})
-t.test('access public on scoped package', async t => {
- const name = '@scoped/npm-access-public-pkg'
- const { npm, joinedOutput, logs } = await loadMockNpm(t, {
- config: {
- ...auth,
- },
- prefixDir: {
- 'package.json': JSON.stringify({ name }),
- },
- })
- const registry = new MockRegistry({
- tap: t,
- registry: npm.config.get('registry'),
- authorization: 'test-auth-token',
+t.test('grant', t => {
+ t.test('invalid permissions', async t => {
+ const { npm } = await loadMockNpm(t)
+ await t.rejects(npm.exec('access', ['grant', 'other']), { code: 'EUSAGE' })
})
- registry.access({ spec: name, access: 'public' })
- await npm.exec('access', ['public'])
- t.match(logs.warn[0], ['access', 'public subcommand will be removed in the next version of npm'])
- t.equal(joinedOutput(), '')
-})
-t.test('access public on missing package.json', async t => {
- const { npm } = await loadMockNpm(t)
- await t.rejects(
- npm.exec('access', ['public']),
- /no package name passed to command and no package.json found/,
- 'should throw no package.json found error'
- )
-})
+ t.test('no permissions', async t => {
+ const { npm } = await loadMockNpm(t)
+ await t.rejects(npm.exec('access', ['grant', 'read-only']), { code: 'EUSAGE' })
+ })
-t.test('access public on invalid package.json', async t => {
- const { npm } = await loadMockNpm(t, {
- prefixDir: {
- 'package.json': '{\n',
- node_modules: {},
- },
+ t.test('read-only', async t => {
+ const { npm } = await loadMockNpm(t)
+ const registry = new MockRegistry({
+ tap: t,
+ registry: npm.config.get('registry'),
+ })
+ const permissions = 'read-only'
+ registry.setPermissions({ spec: '@npmcli/test-package', team: '@npm:test-team', permissions })
+ await npm.exec('access', ['grant', permissions, '@npm:test-team', '@npmcli/test-package'])
})
- await t.rejects(
- npm.exec('access', ['public']),
- { code: 'EJSONPARSE' },
- 'should throw failed to parse package.json'
- )
+ t.end()
})
-t.test('access restricted on unscoped package', async t => {
- const { npm } = await loadMockNpm(t, {
- prefixDir: {
- 'package.json': JSON.stringify({
- name: 'npm-access-restricted-pkg',
- }),
- },
+t.test('revoke', t => {
+ t.test('success', async t => {
+ const { npm } = await loadMockNpm(t)
+ const registry = new MockRegistry({
+ tap: t,
+ registry: npm.config.get('registry'),
+ })
+ registry.removePermissions({ spec: '@npmcli/test-package', team: '@npm:test-team' })
+ await npm.exec('access', ['revoke', '@npm:test-team', '@npmcli/test-package'])
})
- await t.rejects(
- npm.exec('access', ['public']),
- /This command is only available for scoped packages/,
- 'should throw scoped-restricted error'
- )
+ t.end()
})
-t.test('access restricted on scoped package', async t => {
- const name = '@scoped/npm-access-restricted-pkg'
- const { npm, joinedOutput, logs } = await loadMockNpm(t, {
- config: {
- ...auth,
- },
- prefixDir: {
- 'package.json': JSON.stringify({ name }),
- },
+t.test('list', t => {
+ const packages = {
+ '@npmcli/test-package': 'read',
+ '@npmcli/other-package': 'write',
+ }
+ const collaborators = {
+ npm: 'write',
+ github: 'read',
+ }
+ t.test('invalid subcommand', async t => {
+ const { npm } = await loadMockNpm(t)
+ await t.rejects(npm.exec('access', ['list', 'other'], { code: 'EUSAGE' }))
})
- const registry = new MockRegistry({
- tap: t,
- registry: npm.config.get('registry'),
- authorization: 'test-auth-token',
+
+ t.test('packages explicit user', async t => {
+ const { npm, outputs } = await loadMockNpm(t)
+ const registry = new MockRegistry({
+ tap: t,
+ registry: npm.config.get('registry'),
+ })
+ registry.getPackages({ team: '@npm:test-team', packages })
+ await npm.exec('access', ['list', 'packages', '@npm:test-team'])
+ t.same(outputs, [
+ ['@npmcli/other-package: read-write'],
+ ['@npmcli/test-package: read-only'],
+ ])
})
- registry.access({ spec: name, access: 'restricted' })
- await npm.exec('access', ['restricted'])
- t.match(logs.warn[0],
- ['access', 'restricted subcommand will be removed in the next version of npm']
- )
- t.equal(joinedOutput(), '')
-})
-t.test('access restricted on missing package.json', async t => {
- const { npm } = await loadMockNpm(t)
- await t.rejects(
- npm.exec('access', ['restricted']),
- /no package name passed to command and no package.json found/,
- 'should throw no package.json found error'
- )
-})
+ t.test('packages infer user', async t => {
+ const { npm, outputs } = await loadMockNpm(t, { config: { ...auth } })
+ const registry = new MockRegistry({
+ tap: t,
+ registry: npm.config.get('registry'),
+ authorization: token,
+ })
+ registry.whoami({ username: 'npm' })
+ registry.getPackages({ team: 'npm', packages })
+ await npm.exec('access', ['list', 'packages'])
+ t.same(outputs, [
+ ['@npmcli/other-package: read-write'],
+ ['@npmcli/test-package: read-only'],
+ ])
+ })
-t.test('access restricted on invalid package.json', async t => {
- const { npm } = await loadMockNpm(t, {
- prefixDir: {
- 'package.json': '{\n',
- node_modules: {},
- },
+ t.test('packages json', async t => {
+ const { npm, joinedOutput } = await loadMockNpm(t, { config: { json: true } })
+ const registry = new MockRegistry({
+ tap: t,
+ registry: npm.config.get('registry'),
+ })
+ registry.getPackages({ team: '@npm:test-team', packages })
+ await npm.exec('access', ['list', 'packages', '@npm:test-team'])
+ t.same(JSON.parse(joinedOutput()), {
+ '@npmcli/test-package': 'read-only',
+ '@npmcli/other-package': 'read-write',
+ })
})
- await t.rejects(
- npm.exec('access', ['restricted']),
- { code: 'EJSONPARSE' },
- 'should throw failed to parse package.json'
- )
-})
-t.test('access grant read-only', async t => {
- const { npm, joinedOutput } = await loadMockNpm(t, {
- config: {
- ...auth,
- },
+ t.test('collaborators explicit package', async t => {
+ const { npm, outputs } = await loadMockNpm(t)
+ const registry = new MockRegistry({
+ tap: t,
+ registry: npm.config.get('registry'),
+ })
+ registry.getCollaborators({ spec: '@npmcli/test-package', collaborators })
+ await npm.exec('access', ['list', 'collaborators', '@npmcli/test-package'])
+ t.same(outputs, [
+ ['github: read-only'],
+ ['npm: read-write'],
+ ])
})
- const registry = new MockRegistry({
- tap: t,
- registry: npm.config.get('registry'),
- authorization: 'test-auth-token',
+
+ t.test('collaborators user', async t => {
+ const { npm, outputs } = await loadMockNpm(t)
+ const registry = new MockRegistry({
+ tap: t,
+ registry: npm.config.get('registry'),
+ })
+ registry.getCollaborators({ spec: '@npmcli/test-package', collaborators })
+ await npm.exec('access', ['list', 'collaborators', '@npmcli/test-package', 'npm'])
+ t.same(outputs, [
+ ['npm: read-write'],
+ ])
})
- registry.grant({ spec: '@scoped/another', team: 'myorg:myteam', permissions: 'read-only' })
- await npm.exec('access', ['grant', 'read-only', 'myorg:myteam', '@scoped/another'])
- t.equal(joinedOutput(), '')
+ t.end()
})
-t.test('access grant read-write', async t => {
- const { npm, joinedOutput } = await loadMockNpm(t, {
- config: {
- ...auth,
- },
- })
- const registry = new MockRegistry({
- tap: t,
- registry: npm.config.get('registry'),
- authorization: 'test-auth-token',
+t.test('get', t => {
+ t.test('invalid subcommand', async t => {
+ const { npm } = await loadMockNpm(t)
+ await t.rejects(npm.exec('access', ['get', 'other'], { code: 'EUSAGE' }))
})
- registry.grant({ spec: '@scoped/another', team: 'myorg:myteam', permissions: 'read-write' })
- await npm.exec('access', ['grant', 'read-write', 'myorg:myteam', '@scoped/another'])
- t.equal(joinedOutput(), '')
-})
-t.test('access grant current cwd', async t => {
- const { npm, joinedOutput } = await loadMockNpm(t, {
- config: {
- ...auth,
- },
- prefixDir: {
- 'package.json': JSON.stringify({
- name: 'yargs',
- }),
- },
+ t.test('status explicit package', async t => {
+ const { npm, outputs } = await loadMockNpm(t)
+ const registry = new MockRegistry({
+ tap: t,
+ registry: npm.config.get('registry'),
+ })
+ registry.getVisibility({ spec: '@npmcli/test-package', visibility: { public: true } })
+ await npm.exec('access', ['get', 'status', '@npmcli/test-package'])
+ t.same(outputs, [['@npmcli/test-package: public']])
})
- const registry = new MockRegistry({
- tap: t,
- registry: npm.config.get('registry'),
- authorization: 'test-auth-token',
+ t.test('status implicit package', async t => {
+ const { npm, outputs } = await loadMockNpm(t, {
+ prefixDir: {
+ 'package.json': JSON.stringify({ name: '@npmcli/test-package' }),
+ },
+ })
+ const registry = new MockRegistry({
+ tap: t,
+ registry: npm.config.get('registry'),
+ })
+ registry.getVisibility({ spec: '@npmcli/test-package', visibility: { public: true } })
+ await npm.exec('access', ['get', 'status'])
+ t.same(outputs, [['@npmcli/test-package: public']])
})
- registry.grant({ spec: 'yargs', team: 'myorg:myteam', permissions: 'read-write' })
- await npm.exec('access', ['grant', 'read-write', 'myorg:myteam'])
- t.equal(joinedOutput(), '')
-})
-
-t.test('access grant others', async t => {
- const { npm } = await loadMockNpm(t)
- await t.rejects(
- npm.exec('access', [
- 'grant',
- 'rerere',
- 'myorg:myteam',
- '@scoped/another',
- ]),
- /First argument must be either `read-only` or `read-write`./,
- 'should throw unrecognized argument error'
- )
-})
-
-t.test('access grant missing team args', async t => {
- const { npm } = await loadMockNpm(t)
- await t.rejects(
- npm.exec('access', [
- 'grant',
- 'read-only',
- undefined,
- '@scoped/another',
- ]),
- /`<scope:team>` argument is required./,
- 'should throw missing argument error'
- )
-})
-
-t.test('access grant malformed team arg', async t => {
- const { npm } = await loadMockNpm(t)
- await t.rejects(
- npm.exec('access', [
- 'grant',
- 'read-only',
- 'foo',
- '@scoped/another',
- ]),
- /Second argument used incorrect format.\n/,
- 'should throw malformed arg error'
- )
-})
-
-t.test('access 2fa-required', async t => {
- const { npm, joinedOutput, logs } = await loadMockNpm(t, {
- config: {
- ...auth,
- },
+ t.test('status no package', async t => {
+ const { npm } = await loadMockNpm(t)
+ await t.rejects(
+ npm.exec('access', ['get', 'status']),
+ { code: 'ENOENT' }
+ )
})
- const registry = new MockRegistry({
- tap: t,
- registry: npm.config.get('registry'),
- authorization: 'test-auth-token',
+ t.test('status invalid package', async t => {
+ const { npm } = await loadMockNpm(t, {
+ prefixDir: { 'package.json': '[not:valid_json}' },
+ })
+ await t.rejects(
+ npm.exec('access', ['get', 'status']),
+ { code: 'EJSONPARSE' }
+ )
})
- registry.access({ spec: '@scope/pkg', publishRequires2fa: true })
- await npm.exec('access', ['2fa-required', '@scope/pkg'])
- t.match(logs.warn[0],
- ['access', '2fa-required subcommand will be removed in the next version of npm']
- )
- t.equal(joinedOutput(), '')
+ t.test('status json', async t => {
+ const { npm, joinedOutput } = await loadMockNpm(t, { config: { json: true } })
+ const registry = new MockRegistry({
+ tap: t,
+ registry: npm.config.get('registry'),
+ })
+ registry.getVisibility({ spec: '@npmcli/test-package', visibility: { public: true } })
+ await npm.exec('access', ['get', 'status', '@npmcli/test-package'])
+ t.same(JSON.parse(joinedOutput()), { '@npmcli/test-package': 'public' })
+ })
+ t.end()
})
-t.test('access 2fa-not-required', async t => {
- const { npm, joinedOutput, logs } = await loadMockNpm(t, {
- config: {
- ...auth,
- },
+t.test('set', t => {
+ t.test('status=public', async t => {
+ const { npm, outputs } = await loadMockNpm(t)
+ const registry = new MockRegistry({
+ tap: t,
+ registry: npm.config.get('registry'),
+ })
+ registry.setAccess({ spec: '@npmcli/test-package', body: { access: 'public' } })
+ registry.getVisibility({ spec: '@npmcli/test-package', visibility: { public: true } })
+ await npm.exec('access', ['set', 'status=public', '@npmcli/test-package'])
+ t.same(outputs, [['@npmcli/test-package: public']])
})
- const registry = new MockRegistry({
- tap: t,
- registry: npm.config.get('registry'),
- authorization: 'test-auth-token',
+ t.test('status=private', async t => {
+ const { npm, outputs } = await loadMockNpm(t)
+ const registry = new MockRegistry({
+ tap: t,
+ registry: npm.config.get('registry'),
+ })
+ registry.setAccess({ spec: '@npmcli/test-package', body: { access: 'restricted' } })
+ registry.getVisibility({ spec: '@npmcli/test-package', visibility: { public: false } })
+ await npm.exec('access', ['set', 'status=private', '@npmcli/test-package'])
+ t.same(outputs, [['@npmcli/test-package: private']])
})
- registry.access({ spec: '@scope/pkg', publishRequires2fa: false })
- await npm.exec('access', ['2fa-not-required', '@scope/pkg'])
- t.match(logs.warn[0],
- ['access', '2fa-not-required subcommand will be removed in the next version of npm']
- )
- t.equal(joinedOutput(), '')
-})
-
-t.test('access revoke', async t => {
- const { npm, joinedOutput } = await loadMockNpm(t, {
- config: {
- ...auth,
- },
+ t.test('status=invalid', async t => {
+ const { npm } = await loadMockNpm(t)
+ await t.rejects(
+ npm.exec('access', ['set', 'status=invalid', '@npmcli/test-package']),
+ { code: 'EUSAGE' }
+ )
})
- const registry = new MockRegistry({
- tap: t,
- registry: npm.config.get('registry'),
- authorization: 'test-auth-token',
+ t.test('status non scoped package', async t => {
+ const { npm } = await loadMockNpm(t)
+ await t.rejects(
+ npm.exec('access', ['set', 'status=public', 'npm']),
+ { code: 'EUSAGE' }
+ )
})
- registry.revoke({ spec: '@scoped/another', team: 'myorg:myteam' })
- await npm.exec('access', ['revoke', 'myorg:myteam', '@scoped/another'])
- t.equal(joinedOutput(), '')
-})
-
-t.test('access revoke missing team args', async t => {
- const { npm } = await loadMockNpm(t)
- await t.rejects(
- npm.exec('access', [
- 'revoke',
- undefined,
- '@scoped/another',
- ]),
- /`<scope:team>` argument is required./,
- 'should throw missing argument error'
- )
-})
-
-t.test('access revoke malformed team arg', async t => {
- const { npm } = await loadMockNpm(t)
- await t.rejects(
- npm.exec('access', [
- 'revoke',
- 'foo',
- '@scoped/another',
- ]),
- /First argument used incorrect format.\n/,
- 'should throw malformed arg error'
- )
-})
-
-t.test('npm access ls-packages with no team', async t => {
- const { npm, joinedOutput, logs } = await loadMockNpm(t, {
- config: {
- ...auth,
- },
+ t.test('mfa=none', async t => {
+ const { npm } = await loadMockNpm(t)
+ const registry = new MockRegistry({
+ tap: t,
+ registry: npm.config.get('registry'),
+ })
+ registry.setAccess({ spec: '@npmcli/test-package',
+ body: {
+ publish_requires_tfa: false,
+ } })
+ await npm.exec('access', ['set', 'mfa=none', '@npmcli/test-package'])
})
- const registry = new MockRegistry({
- tap: t,
- registry: npm.config.get('registry'),
- authorization: 'test-auth-token',
+ t.test('mfa=publish', async t => {
+ const { npm } = await loadMockNpm(t)
+ const registry = new MockRegistry({
+ tap: t,
+ registry: npm.config.get('registry'),
+ })
+ registry.setAccess({ spec: '@npmcli/test-package',
+ body: {
+ publish_requires_tfa: true,
+ automation_token_overrides_tfa: false,
+ } })
+ await npm.exec('access', ['set', 'mfa=publish', '@npmcli/test-package'])
})
- const team = 'foo'
- const packages = { 'test-package': 'read-write' }
- registry.whoami({ username: team })
- registry.lsPackages({ team, packages })
- await npm.exec('access', ['ls-packages'])
- t.match(logs.warn[0],
- ['access', 'ls-packages subcommand will be removed in the next version of npm']
- )
- t.match(JSON.parse(joinedOutput()), packages)
-})
-
-t.test('access ls-packages on team', async t => {
- const { npm, joinedOutput } = await loadMockNpm(t, {
- config: {
- ...auth,
- },
+ t.test('mfa=automation', async t => {
+ const { npm } = await loadMockNpm(t)
+ const registry = new MockRegistry({
+ tap: t,
+ registry: npm.config.get('registry'),
+ })
+ registry.setAccess({ spec: '@npmcli/test-package',
+ body: {
+ publish_requires_tfa: true,
+ automation_token_overrides_tfa: true,
+ } })
+ await npm.exec('access', ['set', 'mfa=automation', '@npmcli/test-package'])
})
- const registry = new MockRegistry({
- tap: t,
- registry: npm.config.get('registry'),
- authorization: 'test-auth-token',
+ t.test('mfa=invalid', async t => {
+ const { npm } = await loadMockNpm(t)
+ await t.rejects(
+ npm.exec('access', ['set', 'mfa=invalid']),
+ { code: 'EUSAGE' }
+ )
})
- const team = 'myorg:myteam'
- const packages = { 'test-package': 'read-write' }
- registry.lsPackages({ team, packages })
- await npm.exec('access', ['ls-packages', 'myorg:myteam'])
- t.match(JSON.parse(joinedOutput()), packages)
-})
-
-t.test('access ls-collaborators on current', async t => {
- const { npm, joinedOutput, logs } = await loadMockNpm(t, {
- config: {
- ...auth,
- },
- prefixDir: {
- 'package.json': JSON.stringify({
- name: 'yargs',
- }),
- },
+ t.test('2fa=none', async t => {
+ const { npm } = await loadMockNpm(t)
+ const registry = new MockRegistry({
+ tap: t,
+ registry: npm.config.get('registry'),
+ })
+ registry.setAccess({ spec: '@npmcli/test-package',
+ body: {
+ publish_requires_tfa: false,
+ } })
+ await npm.exec('access', ['set', '2fa=none', '@npmcli/test-package'])
})
- const registry = new MockRegistry({
- tap: t,
- registry: npm.config.get('registry'),
- authorization: 'test-auth-token',
+ t.test('2fa=publish', async t => {
+ const { npm } = await loadMockNpm(t)
+ const registry = new MockRegistry({
+ tap: t,
+ registry: npm.config.get('registry'),
+ })
+ registry.setAccess({ spec: '@npmcli/test-package',
+ body: {
+ publish_requires_tfa: true,
+ automation_token_overrides_tfa: false,
+ } })
+ await npm.exec('access', ['set', '2fa=publish', '@npmcli/test-package'])
})
- const collaborators = { 'test-user': 'read-write' }
- registry.lsCollaborators({ spec: 'yargs', collaborators })
- await npm.exec('access', ['ls-collaborators'])
- t.match(logs.warn[0],
- ['access', 'ls-collaborators subcommand will be removed in the next version of npm']
- )
- t.match(JSON.parse(joinedOutput()), collaborators)
-})
-
-t.test('access ls-collaborators on spec', async t => {
- const { npm, joinedOutput } = await loadMockNpm(t, {
- config: {
- ...auth,
- },
+ t.test('2fa=automation', async t => {
+ const { npm } = await loadMockNpm(t)
+ const registry = new MockRegistry({
+ tap: t,
+ registry: npm.config.get('registry'),
+ })
+ registry.setAccess({ spec: '@npmcli/test-package',
+ body: {
+ publish_requires_tfa: true,
+ automation_token_overrides_tfa: true,
+ } })
+ await npm.exec('access', ['set', '2fa=automation', '@npmcli/test-package'])
})
- const registry = new MockRegistry({
- tap: t,
- registry: npm.config.get('registry'),
- authorization: 'test-auth-token',
+ t.test('2fa=invalid', async t => {
+ const { npm } = await loadMockNpm(t)
+ await t.rejects(
+ npm.exec('access', ['set', '2fa=invalid']),
+ { code: 'EUSAGE' }
+ )
})
- const collaborators = { 'test-user': 'read-write' }
- registry.lsCollaborators({ spec: 'yargs', collaborators })
- await npm.exec('access', ['ls-collaborators', 'yargs'])
- t.match(JSON.parse(joinedOutput()), collaborators)
+
+ t.end()
})
diff --git a/test/lib/commands/deprecate.js b/test/lib/commands/deprecate.js
index 3a610a703..57ed9c93b 100644
--- a/test/lib/commands/deprecate.js
+++ b/test/lib/commands/deprecate.js
@@ -32,7 +32,7 @@ t.test('completion', async t => {
})
registry.whoami({ username: user, times: 4 })
- registry.lsPackages({ team: user, packages, times: 4 })
+ registry.getPackages({ team: user, packages, times: 4 })
await Promise.all([
testComp([], ['foo', 'bar', 'baz']),
testComp(['b'], ['bar', 'baz']),
@@ -42,9 +42,12 @@ t.test('completion', async t => {
await testComp(['foo', 'something'], [])
- registry.whoami({ statusCode: 404, body: {} })
+ registry.whoami({ responseCode: 401, body: {} })
- t.rejects(testComp([], []), { code: 'EINVALIDTYPE' })
+ await t.rejects(
+ testComp([], []),
+ { code: 'E401' }
+ )
})
t.test('no args', async t => {
diff --git a/test/lib/commands/unpublish.js b/test/lib/commands/unpublish.js
index 28f93ea3e..9efd2a147 100644
--- a/test/lib/commands/unpublish.js
+++ b/test/lib/commands/unpublish.js
@@ -424,7 +424,7 @@ t.test('completion', async t => {
})
await registry.package({ manifest, query: { write: true } })
registry.whoami({ username: user })
- registry.nock.get('/-/org/test-user/package?format=cli').reply(200, { [pkg]: 'write' })
+ registry.getPackages({ team: user, packages: { [pkg]: 'write' } })
await testComp(t, {
argv: ['npm', 'unpublish'],
@@ -446,7 +446,7 @@ t.test('completion', async t => {
manifest.versions = {}
await registry.package({ manifest, query: { write: true } })
registry.whoami({ username: user })
- registry.nock.get('/-/org/test-user/package?format=cli').reply(200, { [pkg]: 'write' })
+ registry.getPackages({ team: user, packages: { [pkg]: 'write' } })
await testComp(t, {
argv: ['npm', 'unpublish'],
@@ -465,11 +465,12 @@ t.test('completion', async t => {
authorization: 'test-auth-token',
})
registry.whoami({ username: user })
- registry.nock.get('/-/org/test-user/package?format=cli').reply(200, {
- [pkg]: 'write',
- [`${pkg}a`]: 'write',
- [`${pkg}b`]: 'write',
- })
+ registry.getPackages({ team: user,
+ packages: {
+ [pkg]: 'write',
+ [`${pkg}a`]: 'write',
+ [`${pkg}b`]: 'write',
+ } })
await testComp(t, {
argv: ['npm', 'unpublish'],
@@ -489,7 +490,7 @@ t.test('completion', async t => {
authorization: 'test-auth-token',
})
registry.whoami({ username: user })
- registry.nock.get('/-/org/test-user/package?format=cli').reply(200, {})
+ registry.getPackages({ team: user, packages: {} })
await testComp(t, {
argv: ['npm', 'unpublish'],
@@ -506,10 +507,11 @@ t.test('completion', async t => {
authorization: 'test-auth-token',
})
registry.whoami({ username: user })
- registry.nock.get('/-/org/test-user/package?format=cli').reply(200, {
- [pkg]: 'write',
- [`${pkg}a`]: 'write',
- })
+ registry.getPackages({ team: user,
+ packages: {
+ [pkg]: 'write',
+ [`${pkg}a`]: 'write',
+ } })
await testComp(t, {
argv: ['npm', 'unpublish'],
@@ -519,23 +521,6 @@ t.test('completion', async t => {
})
})
- t.test('no pkg names retrieved from user account', async t => {
- const registry = new MockRegistry({
- tap: t,
- registry: npm.config.get('registry'),
- authorization: 'test-auth-token',
- })
- registry.whoami({ username: user })
- registry.nock.get('/-/org/test-user/package?format=cli').reply(200, null)
-
- await testComp(t, {
- argv: ['npm', 'unpublish'],
- partialWord: pkg,
- expect: [],
- title: 'should have no autocomplete',
- })
- })
-
t.test('logged out user', async t => {
const registry = new MockRegistry({
tap: t,