-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: unpublish bugfixes #7039
fix: unpublish bugfixes #7039
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,7 @@ | ||
const libaccess = require('libnpmaccess') | ||
const libunpub = require('libnpmpublish').unpublish | ||
const npa = require('npm-package-arg') | ||
const npmFetch = require('npm-registry-fetch') | ||
const pacote = require('pacote') | ||
const pkgJson = require('@npmcli/package-json') | ||
|
||
const { flatten } = require('@npmcli/config/lib/definitions') | ||
|
@@ -23,12 +23,12 @@ class Unpublish extends BaseCommand { | |
static ignoreImplicitWorkspace = false | ||
|
||
static async getKeysOfVersions (name, opts) { | ||
const pkgUri = npa(name).escapedName | ||
const json = await npmFetch.json(`${pkgUri}?write=true`, { | ||
const packument = await pacote.packument(name, { | ||
hashtagchris marked this conversation as resolved.
Show resolved
Hide resolved
|
||
...opts, | ||
spec: name, | ||
query: { write: true }, | ||
}) | ||
return Object.keys(json.versions) | ||
return Object.keys(packument.versions) | ||
} | ||
|
||
static async completion (args, npm) { | ||
|
@@ -59,28 +59,43 @@ class Unpublish extends BaseCommand { | |
return pkgs | ||
} | ||
|
||
const versions = await this.getKeysOfVersions(pkgs[0], opts) | ||
const versions = await Unpublish.getKeysOfVersions(pkgs[0], opts) | ||
if (!versions.length) { | ||
return pkgs | ||
} else { | ||
return versions.map(v => `${pkgs[0]}@${v}`) | ||
} | ||
} | ||
|
||
async exec (args) { | ||
async exec (args, { localPrefix } = {}) { | ||
if (args.length > 1) { | ||
throw this.usageError() | ||
} | ||
|
||
let spec = args.length && npa(args[0]) | ||
// workspace mode | ||
if (!localPrefix) { | ||
localPrefix = this.npm.localPrefix | ||
} | ||
|
||
const force = this.npm.config.get('force') | ||
const { silent } = this.npm | ||
const dryRun = this.npm.config.get('dry-run') | ||
|
||
let spec | ||
if (args.length) { | ||
spec = npa(args[0]) | ||
if (spec.type !== 'version' && spec.rawSpec !== '*') { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
💭 Looks like There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
throw this.usageError( | ||
'Can only unpublish a single version, or the entire project.\n' + | ||
'Tags and ranges are not supported.' | ||
) | ||
} | ||
} | ||
|
||
log.silly('unpublish', 'args[0]', args[0]) | ||
log.silly('unpublish', 'spec', spec) | ||
|
||
if ((!spec || !spec.rawSpec) && !force) { | ||
if (spec?.rawSpec === '*' && !force) { | ||
throw this.usageError( | ||
'Refusing to delete entire project.\n' + | ||
'Run with --force to do this.' | ||
|
@@ -89,69 +104,63 @@ class Unpublish extends BaseCommand { | |
|
||
const opts = { ...this.npm.flatOptions } | ||
|
||
let pkgName | ||
let pkgVersion | ||
let manifest | ||
let manifestErr | ||
try { | ||
const { content } = await pkgJson.prepare(this.npm.localPrefix) | ||
const { content } = await pkgJson.prepare(localPrefix) | ||
manifest = content | ||
} catch (err) { | ||
manifestErr = err | ||
} | ||
if (spec) { | ||
// If cwd has a package.json with a name that matches the package being | ||
// unpublished, load up the publishConfig | ||
if (manifest && manifest.name === spec.name && manifest.publishConfig) { | ||
flatten(manifest.publishConfig, opts) | ||
} | ||
const versions = await Unpublish.getKeysOfVersions(spec.name, opts) | ||
if (versions.length === 1 && !force) { | ||
throw this.usageError(LAST_REMAINING_VERSION_ERROR) | ||
} | ||
pkgName = spec.name | ||
pkgVersion = spec.type === 'version' ? `@${spec.rawSpec}` : '' | ||
} else { | ||
if (manifestErr) { | ||
if (manifestErr.code === 'ENOENT' || manifestErr.code === 'ENOTDIR') { | ||
// we needed the manifest to figure out the package to unpublish | ||
if (!spec) { | ||
if (err.code === 'ENOENT' || err.code === 'ENOTDIR') { | ||
throw this.usageError() | ||
} else { | ||
throw manifestErr | ||
throw err | ||
wraithgar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} | ||
} | ||
|
||
log.verbose('unpublish', manifest) | ||
|
||
let pkgVersion // for cli output | ||
if (spec) { | ||
pkgVersion = spec.type === 'version' ? `@${spec.rawSpec}` : '' | ||
} else { | ||
spec = npa.resolve(manifest.name, manifest.version) | ||
if (manifest.publishConfig) { | ||
flatten(manifest.publishConfig, opts) | ||
log.verbose('unpublish', manifest) | ||
pkgVersion = manifest.version ? `@${manifest.version}` : '' | ||
hashtagchris marked this conversation as resolved.
Show resolved
Hide resolved
|
||
if (!manifest.version && !force) { | ||
throw this.usageError( | ||
'Refusing to delete entire project.\n' + | ||
'Run with --force to do this.' | ||
) | ||
} | ||
} | ||
|
||
pkgName = manifest.name | ||
pkgVersion = manifest.version ? `@${manifest.version}` : '' | ||
// If localPrefix has a package.json with a name that matches the package | ||
// being unpublished, load up the publishConfig | ||
if (manifest?.name === spec.name && manifest.publishConfig) { | ||
flatten(manifest.publishConfig, opts) | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion: Check |
||
const versions = await Unpublish.getKeysOfVersions(spec.name, opts) | ||
if (versions.length === 1 && spec.rawSpec === versions[0] && !force) { | ||
throw this.usageError(LAST_REMAINING_VERSION_ERROR) | ||
} | ||
if (versions.length === 1) { | ||
pkgVersion = '' | ||
} | ||
|
||
if (!dryRun) { | ||
await otplease(this.npm, opts, o => libunpub(spec, o)) | ||
} | ||
if (!silent) { | ||
this.npm.output(`- ${pkgName}${pkgVersion}`) | ||
this.npm.output(`- ${spec.name}${pkgVersion}`) | ||
} | ||
} | ||
|
||
async execWorkspaces (args) { | ||
await this.setWorkspaces() | ||
|
||
const force = this.npm.config.get('force') | ||
if (!force) { | ||
throw this.usageError( | ||
'Refusing to delete entire project(s).\n' + | ||
'Run with --force to do this.' | ||
) | ||
} | ||
|
||
for (const name of this.workspaceNames) { | ||
await this.exec([name]) | ||
for (const path of this.workspacePaths) { | ||
await this.exec(args, { localPrefix: path }) | ||
hashtagchris marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.