index.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. #!/usr/bin/env node
  2. const run = conf => {
  3. const pacote = require('../')
  4. switch (conf._[0]) {
  5. case 'resolve':
  6. case 'manifest':
  7. case 'packument':
  8. if (conf._[0] === 'resolve' && conf.long) {
  9. return pacote.manifest(conf._[1], conf).then(mani => ({
  10. resolved: mani._resolved,
  11. integrity: mani._integrity,
  12. from: mani._from,
  13. }))
  14. }
  15. return pacote[conf._[0]](conf._[1], conf)
  16. case 'tarball':
  17. if (!conf._[2] || conf._[2] === '-') {
  18. return pacote.tarball.stream(conf._[1], stream => {
  19. stream.pipe(
  20. conf.testStdout ||
  21. /* istanbul ignore next */
  22. process.stdout
  23. )
  24. // make sure it resolves something falsey
  25. return stream.promise().then(() => {
  26. return false
  27. })
  28. }, conf)
  29. } else {
  30. return pacote.tarball.file(conf._[1], conf._[2], conf)
  31. }
  32. case 'extract':
  33. return pacote.extract(conf._[1], conf._[2], conf)
  34. default: /* istanbul ignore next */ {
  35. throw new Error(`bad command: ${conf._[0]}`)
  36. }
  37. }
  38. }
  39. const version = require('../package.json').version
  40. const usage = () =>
  41. `Pacote - The JavaScript Package Handler, v${version}
  42. Usage:
  43. pacote resolve <spec>
  44. Resolve a specifier and output the fully resolved target
  45. Returns integrity and from if '--long' flag is set.
  46. pacote manifest <spec>
  47. Fetch a manifest and print to stdout
  48. pacote packument <spec>
  49. Fetch a full packument and print to stdout
  50. pacote tarball <spec> [<filename>]
  51. Fetch a package tarball and save to <filename>
  52. If <filename> is missing or '-', the tarball will be streamed to stdout.
  53. pacote extract <spec> <folder>
  54. Extract a package to the destination folder.
  55. Configuration values all match the names of configs passed to npm, or
  56. options passed to Pacote. Additional flags for this executable:
  57. --long Print an object from 'resolve', including integrity and spec.
  58. --json Print result objects as JSON rather than node's default.
  59. (This is the default if stdout is not a TTY.)
  60. --help -h Print this helpful text.
  61. For example '--cache=/path/to/folder' will use that folder as the cache.
  62. `
  63. const shouldJSON = (conf, result) =>
  64. conf.json ||
  65. !process.stdout.isTTY &&
  66. conf.json === undefined &&
  67. result &&
  68. typeof result === 'object'
  69. const pretty = (conf, result) =>
  70. shouldJSON(conf, result) ? JSON.stringify(result, 0, 2) : result
  71. let addedLogListener = false
  72. const main = args => {
  73. const conf = parse(args)
  74. if (conf.help || conf.h) {
  75. return console.log(usage())
  76. }
  77. if (!addedLogListener) {
  78. process.on('log', console.error)
  79. addedLogListener = true
  80. }
  81. try {
  82. return run(conf)
  83. .then(result => result && console.log(pretty(conf, result)))
  84. .catch(er => {
  85. console.error(er)
  86. process.exit(1)
  87. })
  88. } catch (er) {
  89. console.error(er.message)
  90. console.error(usage())
  91. }
  92. }
  93. const parseArg = arg => {
  94. const split = arg.slice(2).split('=')
  95. const k = split.shift()
  96. const v = split.join('=')
  97. const no = /^no-/.test(k) && !v
  98. const key = (no ? k.slice(3) : k)
  99. .replace(/^tag$/, 'defaultTag')
  100. .replace(/-([a-z])/g, (_, c) => c.toUpperCase())
  101. const value = v ? v.replace(/^~/, process.env.HOME) : !no
  102. return { key, value }
  103. }
  104. const parse = args => {
  105. const conf = {
  106. _: [],
  107. cache: process.env.HOME + '/.npm/_cacache',
  108. }
  109. let dashdash = false
  110. args.forEach(arg => {
  111. if (dashdash) {
  112. conf._.push(arg)
  113. } else if (arg === '--') {
  114. dashdash = true
  115. } else if (arg === '-h') {
  116. conf.help = true
  117. } else if (/^--/.test(arg)) {
  118. const { key, value } = parseArg(arg)
  119. conf[key] = value
  120. } else {
  121. conf._.push(arg)
  122. }
  123. })
  124. return conf
  125. }
  126. if (module === require.main) {
  127. main(process.argv.slice(2))
  128. } else {
  129. module.exports = {
  130. main,
  131. run,
  132. usage,
  133. parseArg,
  134. parse,
  135. }
  136. }