PATH:
usr
/
local
/
lib
/
node_modules
/
npm
/
lib
'use strict' const path = require('path') const archy = require('archy') const figgyPudding = require('figgy-pudding') const readPackageTree = require('read-package-tree') const npm = require('./npm.js') const npmConfig = require('./config/figgy-config.js') const fetchPackageMetadata = require('./fetch-package-metadata.js') const computeMetadata = require('./install/deps.js').computeMetadata const readShrinkwrap = require('./install/read-shrinkwrap.js') const mutateIntoLogicalTree = require('./install/mutate-into-logical-tree.js') const output = require('./utils/output.js') const openUrl = require('./utils/open-url.js') const { getFundingInfo, retrieveFunding, validFundingUrl } = require('./utils/funding.js') const FundConfig = figgyPudding({ browser: {}, // used by ./utils/open-url global: {}, json: {}, unicode: {} }) module.exports = fundCmd const usage = require('./utils/usage') fundCmd.usage = usage( 'fund', 'npm fund [--json]', 'npm fund [--browser] [[<@scope>/]<pkg>' ) fundCmd.completion = function (opts, cb) { const argv = opts.conf.argv.remain switch (argv[2]) { case 'fund': return cb(null, []) default: return cb(new Error(argv[2] + ' not recognized')) } } function printJSON (fundingInfo) { return JSON.stringify(fundingInfo, null, 2) } // the human-printable version does some special things that turned out to // be very verbose but hopefully not hard to follow: we stack up items // that have a shared url/type and make sure they're printed at the highest // level possible, in that process they also carry their dependencies along // with them, moving those up in the visual tree function printHuman (fundingInfo, opts) { // mapping logic that keeps track of seen items in order to be able // to push all other items from the same type/url in the same place const seen = new Map() function seenKey ({ type, url } = {}) { return url ? String(type) + String(url) : null } function setStackedItem (funding, result) { const key = seenKey(funding) if (key && !seen.has(key)) seen.set(key, result) } function retrieveStackedItem (funding) { const key = seenKey(funding) if (key && seen.has(key)) return seen.get(key) } // --- const getFundingItems = (fundingItems) => Object.keys(fundingItems || {}).map((fundingItemName) => { // first-level loop, prepare the pretty-printed formatted data const fundingItem = fundingItems[fundingItemName] const { version, funding } = fundingItem const { type, url } = funding || {} const printableVersion = version ? `@${version}` : '' const printableType = type && { label: `type: ${funding.type}` } const printableUrl = url && { label: `url: ${funding.url}` } const result = { fundingItem, label: fundingItemName + printableVersion, nodes: [] } if (printableType) { result.nodes.push(printableType) } if (printableUrl) { result.nodes.push(printableUrl) } setStackedItem(funding, result) return result }).reduce((res, result) => { // recurse and exclude nodes that are going to be stacked together const { fundingItem } = result const { dependencies, funding } = fundingItem const items = getFundingItems(dependencies) const stackedResult = retrieveStackedItem(funding) items.forEach(i => result.nodes.push(i)) if (stackedResult && stackedResult !== result) { stackedResult.label += `, ${result.label}` items.forEach(i => stackedResult.nodes.push(i)) return res } res.push(result) return res }, []) const [ result ] = getFundingItems({ [fundingInfo.name]: { dependencies: fundingInfo.dependencies, funding: fundingInfo.funding, version: fundingInfo.version } }) return archy(result, '', { unicode: opts.unicode }) } function openFundingUrl (packageName, cb) { function getUrlAndOpen (packageMetadata) { const { funding } = packageMetadata const { type, url } = retrieveFunding(funding) || {} const noFundingError = new Error(`No funding method available for: ${packageName}`) noFundingError.code = 'ENOFUND' const typePrefix = type ? `${type} funding` : 'Funding' const msg = `${typePrefix} available at the following URL` if (validFundingUrl(funding)) { openUrl(url, msg, cb) } else { throw noFundingError } } fetchPackageMetadata( packageName, '.', { fullMetadata: true }, function (err, packageMetadata) { if (err) return cb(err) getUrlAndOpen(packageMetadata) } ) } function fundCmd (args, cb) { const opts = FundConfig(npmConfig()) const dir = path.resolve(npm.dir, '..') const packageName = args[0] if (opts.global) { const err = new Error('`npm fund` does not support globals') err.code = 'EFUNDGLOBAL' throw err } if (packageName) { openFundingUrl(packageName, cb) return } readPackageTree(dir, function (err, tree) { if (err) { process.exitCode = 1 return cb(err) } readShrinkwrap.andInflate(tree, function () { const fundingInfo = getFundingInfo( mutateIntoLogicalTree.asReadInstalled( computeMetadata(tree) ) ) const print = opts.json ? printJSON : printHuman output( print( fundingInfo, opts ) ) cb(err, tree) }) }) }
[-] star.js
[edit]
[-] ping.js
[edit]
[-] xmas.js
[edit]
[+]
search
[-] stop.js
[edit]
[-] team.js
[edit]
[-] run-script.js
[edit]
[-] edit.js
[edit]
[-] explore.js
[edit]
[-] access.js
[edit]
[-] repo.js
[edit]
[-] root.js
[edit]
[-] completion.js
[edit]
[-] bugs.js
[edit]
[-] restart.js
[edit]
[+]
..
[-] pack.js
[edit]
[-] unbuild.js
[edit]
[-] fetch-package-metadata.md
[edit]
[-] npm.js
[edit]
[-] install-test.js
[edit]
[+]
utils
[-] org.js
[edit]
[-] dedupe.js
[edit]
[+]
auth
[-] visnup.js
[edit]
[-] test.js
[edit]
[-] audit.js
[edit]
[-] install-ci-test.js
[edit]
[-] cache.js
[edit]
[-] outdated.js
[edit]
[-] link.js
[edit]
[-] substack.js
[edit]
[-] logout.js
[edit]
[-] install.js
[edit]
[-] fetch-package-metadata.js
[edit]
[-] fund.js
[edit]
[-] ci.js
[edit]
[-] get.js
[edit]
[-] profile.js
[edit]
[-] uninstall.js
[edit]
[+]
doctor
[-] init.js
[edit]
[-] prune.js
[edit]
[-] dist-tag.js
[edit]
[-] search.js
[edit]
[-] view.js
[edit]
[-] owner.js
[edit]
[+]
config
[-] rebuild.js
[edit]
[-] start.js
[edit]
[-] config.js
[edit]
[-] update.js
[edit]
[-] docs.js
[edit]
[+]
install
[-] build.js
[edit]
[-] help.js
[edit]
[-] ls.js
[edit]
[-] deprecate.js
[edit]
[-] hook.js
[edit]
[-] publish.js
[edit]
[-] prefix.js
[edit]
[-] adduser.js
[edit]
[-] shrinkwrap.js
[edit]
[-] help-search.js
[edit]
[-] stars.js
[edit]
[-] doctor.js
[edit]
[-] set.js
[edit]
[-] whoami.js
[edit]
[-] version.js
[edit]
[-] bin.js
[edit]
[-] token.js
[edit]
[-] unpublish.js
[edit]