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