1// Base command for opening urls from a package manifest (bugs, docs, repo) 2 3const pacote = require('pacote') 4const hostedGitInfo = require('hosted-git-info') 5 6const openUrl = require('./utils/open-url.js') 7const log = require('./utils/log-shim') 8 9const BaseCommand = require('./base-command.js') 10class PackageUrlCommand extends BaseCommand { 11 static params = [ 12 'browser', 13 'registry', 14 'workspace', 15 'workspaces', 16 'include-workspace-root', 17 ] 18 19 static workspaces = true 20 static ignoreImplicitWorkspace = false 21 static usage = ['[<pkgname> [<pkgname> ...]]'] 22 23 async exec (args) { 24 if (!args || !args.length) { 25 args = ['.'] 26 } 27 28 for (const arg of args) { 29 // XXX It is very odd that `where` is how pacote knows to look anywhere 30 // other than the cwd. 31 const opts = { 32 ...this.npm.flatOptions, 33 where: this.npm.localPrefix, 34 fullMetadata: true, 35 } 36 const mani = await pacote.manifest(arg, opts) 37 const url = this.getUrl(arg, mani) 38 log.silly(this.name, 'url', url) 39 await openUrl(this.npm, url, `${mani.name} ${this.name} available at the following URL`) 40 } 41 } 42 43 async execWorkspaces (args) { 44 if (args && args.length) { 45 return this.exec(args) 46 } 47 await this.setWorkspaces() 48 return this.exec(this.workspacePaths) 49 } 50 51 // given a manifest, try to get the hosted git info from it based on 52 // repository (if a string) or repository.url (if an object) returns null 53 // if it's not a valid repo, or not a known hosted repo 54 hostedFromMani (mani) { 55 const r = mani.repository 56 const rurl = !r ? null 57 : typeof r === 'string' ? r 58 : typeof r === 'object' && typeof r.url === 'string' ? r.url 59 : null 60 61 // hgi returns undefined sometimes, but let's always return null here 62 return (rurl && hostedGitInfo.fromUrl(rurl.replace(/^git\+/, ''))) || null 63 } 64} 65module.exports = PackageUrlCommand 66