├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── bin ├── bulk-details ├── delivery ├── details ├── download ├── download-info ├── download-meta ├── get-sha1 ├── get-token └── search ├── cli.js ├── index.js ├── lib ├── api.js ├── app.js └── download.js ├── package-lock.json ├── package.json └── test └── scripts.test.js /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | npm-debug.log 3 | /scratch 4 | .envrc 5 | 6 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '8' 4 | script: 5 | - npm test 6 | env: 7 | global: 8 | - secure: RhFwZKxW8WU84e8fGRqjwUDv7nIv5AovuRaBt0HtyfCQPkeu3ZrRVO6ATobZROt5qa+cS4wuLlpA+mtcf2bPM+ef0PYKKxOpyZK98+ftFinWYQZ0E0ymhHboPcP8dJwqe33YU2g3jaRBodr0Utgez2uwto/R1PuGTXPkeHbtKLo= 9 | - secure: NxQgsbqccaM3ZljQcmTft7N5UfQC7bt4p9OpTm/xqpdOaW1ks592u+0+YkFipRTZOvX6RBZ8YqtwS0Hs+yaP+bhesVNAd3+XHLPgA6g82G263Girgb6tx9OiPDpcLrnPmckcM9fek5rhxmkgDcy7xIULeu3CQJsWZmQv+hlzY/s= 10 | - secure: WdFJ3FbrSszhvX3Jwdb4MZ1tRaJ89zJfLrPqV20XP0YmUG0i3W5daxBm5Ow9f/MIIzU/8WIWBor9ZejssTcl0zrV7wI7FaPvmWWXNt0Io9K/EvmKXN3PBdW/cXo9szKDkDisR9s9bl639+Z0nQ18UVd6oIm/f2viIIyIXfDr3HM= 11 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 David Weinstein 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![NPM](https://nodei.co/npm/google-play-cli.png?downloads=true)](https://nodei.co/npm/google-play-cli/) 2 | 3 | [![Build Status](https://travis-ci.org/dweinstein/node-google-play-cli.png)](https://travis-ci.org/dweinstein/node-google-play-cli) 4 | [![npm version](https://badge.fury.io/js/google-play-cli.svg)](http://badge.fury.io/js/google-play-cli) 5 | 6 | # SYNOPSIS 7 | 8 | Command line tools using the 9 | [`node-google-play`](https://github.com/dweinstein/node-google-play) library. 10 | 11 | # OPTIONS 12 | 13 | The following **environment variables** are used: 14 | 15 | - `GOOGLE_LOGIN` - email address used on a mobile phone. 16 | - `GOOGLE_PASSWORD` - The password used to access the Play service. 17 | - `ANDROID_ID` - the ID for the device for Google. This is the GSF ID *not* the 18 | id from dialing `*#*#8255#*#*`. You can get the gsf id e.g., using the 19 | [device id 20 | app](https://play.google.com/store/apps/details?id=com.evozi.deviceid&hl=en) 21 | 22 | # USAGE 23 | 24 | I use the [`jq`](https://github.com/stedolan/jq) tool to stream the JSON results. 25 | 26 | ## Download 27 | 28 | Download the app to your current directory. 29 | - `$ gp-download air.WatchESPN > air.WatchESPN.apk` 30 | 31 | ## Bulk Details 32 | 33 | - `$ gp-bulk-details air.WatchESPN com.viber.voip | jq '.'` 34 | 35 | ## Delivery info 36 | 37 | This info is sent from the server to the device before downloading the app. 38 | 39 | - `$ gp-delivery air.WatchESPN | jq '.'` 40 | 41 | ## Integrity 42 | 43 | Get the SHA1 checksum for the file from Google. 44 | 45 | ``` 46 | $ gp-get-sha1 air.WatchESPN 47 | 5381ff6fbcb36032aea1c3b83d921b94602c2f3a 48 | ``` 49 | -------------------------------------------------------------------------------- /bin/bulk-details: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict'; 3 | 4 | var api = require('../lib/api'); 5 | 6 | var argv = require('minimist')(process.argv.slice(2)); 7 | var pkgs = argv._; 8 | 9 | if (!pkgs) { 10 | console.error("supply packages"); 11 | process.exit(1); 12 | } 13 | 14 | api.bulkDetails(pkgs).then(function (res) { 15 | console.log('%j', res); 16 | }, function (err) { 17 | console.error(err.toString()); 18 | process.exit(1); 19 | }); 20 | 21 | -------------------------------------------------------------------------------- /bin/delivery: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict'; 3 | 4 | var api = require('../lib/api'); 5 | 6 | var argv = require('minimist')(process.argv.slice(2)); 7 | var pkg = argv._[0] || argv.p; 8 | var vc = argv._[1] || argv.vc; 9 | 10 | if (!pkg) { 11 | console.error('supply package (-p)'); 12 | process.exit(1); 13 | } 14 | 15 | api.details(pkg).then(function (res) { 16 | return vc || res.details.appDetails.versionCode; 17 | }) 18 | .then(function (versionCode) { 19 | return api.deliveryData(pkg, versionCode); 20 | }) 21 | .then(function (info) { 22 | console.log('%j', info); 23 | }, function (err) { 24 | console.error(err.toString()); 25 | process.exit(1); 26 | }); 27 | -------------------------------------------------------------------------------- /bin/details: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict'; 3 | 4 | var api = require('../lib/api'); 5 | 6 | var argv = require('minimist')(process.argv.slice(2)); 7 | var pkg = argv._[0] || argv.p; 8 | 9 | if (!pkg) { 10 | console.error("supply pkg (-p)"); 11 | } 12 | api.details(pkg).then(function (res) { 13 | console.log('%j', res); 14 | }, function (err) { 15 | console.error(err.toString()); 16 | process.exit(1); 17 | }); 18 | 19 | -------------------------------------------------------------------------------- /bin/download: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict'; 3 | 4 | var argv = require('minimist')(process.argv.slice(2)); 5 | var api = require('../lib/api'); 6 | 7 | var pkg = argv._[0] || argv.p; 8 | var vc = argv._[1] || argv.vc; 9 | 10 | if(!pkg) { 11 | console.error("supply pkg (-p)"); 12 | process.exit(1); 13 | } 14 | 15 | require('../lib/download')(api, pkg, vc) 16 | .then(function (stream) { 17 | stream.pipe(process.stdout); 18 | }, function (err) { 19 | console.error(err.toString()); 20 | process.exit(1); 21 | }); 22 | 23 | -------------------------------------------------------------------------------- /bin/download-info: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict'; 3 | 4 | var api = require('../lib/api'); 5 | 6 | var argv = require('minimist')(process.argv.slice(2)); 7 | var pkg = argv._[0] || argv.p; 8 | var vc = argv._[1] || argv.vc; 9 | 10 | if (!pkg) { 11 | console.error("supply package (-p)"); 12 | process.exit(1); 13 | } 14 | 15 | api.details(pkg).then(function (res) { 16 | return vc || res.details.appDetails.versionCode; 17 | }) 18 | .then(function (versionCode) { 19 | return api.downloadInfo(pkg, versionCode); 20 | }) 21 | .then(function (info) { 22 | console.log('%j', info); 23 | }, function (err) { 24 | console.error(err.toString()); 25 | process.exit(1); 26 | }); 27 | 28 | -------------------------------------------------------------------------------- /bin/download-meta: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict'; 3 | 4 | var argv = require('minimist')(process.argv.slice(2)); 5 | var api = require('../lib/api'); 6 | 7 | var pkg = argv._[0] || argv.p; 8 | var vc = argv._[1] || argv.vc; 9 | 10 | if(!pkg) { 11 | console.error("supply pkg (-p)"); 12 | process.exit(1); 13 | } 14 | 15 | require('../lib/app')(api, pkg, vc) 16 | .then(function (res) { 17 | console.log(JSON.stringify(res, null, 2)); 18 | }, function (err) { 19 | console.error(err.toString()); 20 | process.exit(1); 21 | }); 22 | 23 | -------------------------------------------------------------------------------- /bin/get-sha1: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict'; 3 | 4 | var argv = require('minimist')(process.argv.slice(2)); 5 | var api = require('../lib/api'); 6 | 7 | var pkg = argv._[0] || argv.p; 8 | var vc = argv._[1] || argv.vc; 9 | 10 | if(!pkg) { 11 | console.error("supply pkg (-p)"); 12 | process.exit(1); 13 | } 14 | 15 | require('../lib/app')(api, pkg, vc) 16 | .then(function (res) { 17 | console.log(res.sha1); 18 | }, function (err) { 19 | console.error(err.toString()); 20 | process.exit(1); 21 | }); 22 | 23 | -------------------------------------------------------------------------------- /bin/get-token: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict'; 3 | 4 | var api = require('../lib/api'); 5 | 6 | api.login() 7 | .then(function (token) { 8 | console.log(token); 9 | }) 10 | .catch(function (err) { 11 | console.error(err.toString()); 12 | process.exit(1); 13 | }); 14 | -------------------------------------------------------------------------------- /bin/search: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env node 2 | 'use strict'; 3 | 4 | var api = require('../lib/api'); 5 | 6 | var argv = require('minimist')(process.argv.slice(2)); 7 | var term = argv._[0] || argv.t || argv.term ; 8 | var size = argv._[1] || argv.s || argv.size || 1; 9 | var offset = argv._[2] || argv.o || argv.offset || 0; 10 | 11 | if (!term) { 12 | console.error("supply term (-t, --term)"); 13 | process.exit(1); 14 | } 15 | 16 | api.search(term, size, offset) 17 | .then(function (res) { 18 | console.log('%j', res); 19 | }, function (err) { 20 | console.error(err.toString()); 21 | process.exit(1); 22 | }); 23 | 24 | -------------------------------------------------------------------------------- /cli.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | const decamelize = require('decamelize'); 3 | 4 | const USER_AGENT = ( 5 | 'Android-Finsky/6.8.44.F-all%20%5B0%5D%203087104 ' + 6 | '(api=3,versionCode=80684400,sdk=23,device=bullhead,' + 7 | 'hardware=bullhead,product=bullhead,platformVersionRelease=6.0.1,' + 8 | 'model=Nexus%205X,buildId=MHC19Q,isWideScreen=0)' 9 | ); 10 | 11 | const DOWNLOAD_MANAGER_USER_AGENT = ( 12 | 'AndroidDownloadManager/6.0.1 (Linux; U; Android 6.0.1; Nexus 5X Build/MHC19Q)' 13 | ); 14 | 15 | const defaults = { 16 | username: process.env.GOOGLE_LOGIN, 17 | password: process.env.GOOGLE_PASSWORD, 18 | androidId: process.env.ANDROID_ID, 19 | authToken: undefined, 20 | countryCode: 'us', 21 | language: 'en_US', 22 | useCache: false, 23 | debug: process.env.DEBUG, 24 | apiUserAgent: USER_AGENT, 25 | downloadUserAgent: DOWNLOAD_MANAGER_USER_AGENT, 26 | sdkVersion: 23 27 | } 28 | 29 | const alias = Object.keys(defaults).reduce((a, k) => { 30 | a[decamelize(k, '-')] = k; 31 | return a; 32 | }, {}) 33 | 34 | module.exports = require('rc')( 35 | 'gpcli', 36 | defaults, 37 | require('minimist')(process.argv, { 38 | alias: alias 39 | }) 40 | ); 41 | 42 | if (!module.parent) { 43 | console.log(module.exports); 44 | } 45 | 46 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 2 | module.exports = require('./lib/api'); 3 | 4 | -------------------------------------------------------------------------------- /lib/api.js: -------------------------------------------------------------------------------- 1 | var GooglePlayAPI = require('gpapi').GooglePlayAPI; 2 | var cfg = require('../cli') 3 | 4 | var api = GooglePlayAPI(cfg); 5 | 6 | module.exports = api; 7 | 8 | -------------------------------------------------------------------------------- /lib/app.js: -------------------------------------------------------------------------------- 1 | var Long = require('long'); 2 | var extend = require('xtend'); 3 | 4 | function unescape (str) { 5 | return (str + Array(5 - str.length % 4).join('=')).replace(/\-/g,'+').replace(/_/g, '/'); 6 | } 7 | 8 | function decodeDigest (str) { 9 | return new Buffer(unescape(str), 'base64').toString('hex'); 10 | } 11 | 12 | function signatureToSha1 (sig) { 13 | return decodeDigest(sig); 14 | } 15 | 16 | module.exports = function getAppInfo (api, pkg, vc) { 17 | return api.details(pkg) 18 | .then(function (d) { 19 | vc = vc || d.details.appDetails.versionCode; 20 | var basicInfo = { 21 | appCategory: d.details.appDetails.appCategory, 22 | certificateHash: d.details.appDetails.certificateHash.map(signatureToSha1), 23 | certificateSet: d.details.appDetails.certificateSet.map((x) => { 24 | return signatureToSha1(x.certificateHash); 25 | }), 26 | email: d.details.appDetails.developerEmail, 27 | minDownloadCount: Number(d.details.appDetails.numDownloads.replace(/,|\+/g, '').replace('downloads', '')), 28 | name: d.title, 29 | packageName: pkg, 30 | price: d.offer.map(function (m) { return m.formattedAmount; }), 31 | vendor: d.creator, 32 | website: d.details.appDetails.developerWebsite 33 | }; 34 | var checkoutRequired = d.offer.some(function (o) { return o.checkoutFlowRequired; }); 35 | if (checkoutRequired) { 36 | return basicInfo; 37 | } 38 | return api.downloadInfo(pkg, vc) 39 | .then(function (res) { 40 | return extend(basicInfo, { 41 | sha1: signatureToSha1(res.signature), 42 | versionCode: vc, 43 | size: Long.fromValue(res.downloadSize).toNumber() 44 | }); 45 | }); 46 | }); 47 | }; 48 | 49 | -------------------------------------------------------------------------------- /lib/download.js: -------------------------------------------------------------------------------- 1 | 2 | function download(api, pkg, vc) { 3 | return api.details(pkg).then(function (res) { 4 | return vc || res.details.appDetails.versionCode; 5 | }) 6 | .then(function (versionCode) { 7 | return api.download(pkg, versionCode).then(function (res) { 8 | return res; 9 | }); 10 | }); 11 | } 12 | 13 | module.exports = download; 14 | 15 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "google-play-cli", 3 | "version": "4.5.1-0", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "ajv": { 8 | "version": "5.5.0", 9 | "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.0.tgz", 10 | "integrity": "sha1-6yhAdG6dxIvV4GOjbj/UAMXqtak=", 11 | "requires": { 12 | "co": "4.6.0", 13 | "fast-deep-equal": "1.0.0", 14 | "fast-json-stable-stringify": "2.0.0", 15 | "json-schema-traverse": "0.3.1" 16 | } 17 | }, 18 | "ansi-regex": { 19 | "version": "2.1.1", 20 | "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", 21 | "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" 22 | }, 23 | "ascli": { 24 | "version": "1.0.1", 25 | "resolved": "https://registry.npmjs.org/ascli/-/ascli-1.0.1.tgz", 26 | "integrity": "sha1-vPpZdKYvGOgcq660lzKrSoj5Brw=", 27 | "requires": { 28 | "colour": "0.7.1", 29 | "optjs": "3.2.2" 30 | } 31 | }, 32 | "asn1": { 33 | "version": "0.2.3", 34 | "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", 35 | "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=" 36 | }, 37 | "assert-plus": { 38 | "version": "1.0.0", 39 | "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", 40 | "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" 41 | }, 42 | "asynckit": { 43 | "version": "0.4.0", 44 | "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", 45 | "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" 46 | }, 47 | "aws-sign2": { 48 | "version": "0.7.0", 49 | "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", 50 | "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" 51 | }, 52 | "aws4": { 53 | "version": "1.6.0", 54 | "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", 55 | "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=" 56 | }, 57 | "balanced-match": { 58 | "version": "1.0.0", 59 | "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", 60 | "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" 61 | }, 62 | "bcrypt-pbkdf": { 63 | "version": "1.0.1", 64 | "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", 65 | "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", 66 | "optional": true, 67 | "requires": { 68 | "tweetnacl": "0.14.5" 69 | } 70 | }, 71 | "bluebird": { 72 | "version": "3.5.1", 73 | "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", 74 | "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==" 75 | }, 76 | "boom": { 77 | "version": "4.3.1", 78 | "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz", 79 | "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=", 80 | "requires": { 81 | "hoek": "4.2.0" 82 | } 83 | }, 84 | "brace-expansion": { 85 | "version": "1.1.8", 86 | "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", 87 | "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", 88 | "requires": { 89 | "balanced-match": "1.0.0", 90 | "concat-map": "0.0.1" 91 | } 92 | }, 93 | "bytebuffer": { 94 | "version": "5.0.1", 95 | "resolved": "https://registry.npmjs.org/bytebuffer/-/bytebuffer-5.0.1.tgz", 96 | "integrity": "sha1-WC7qSxqHO20CCkjVjfhfC7ps/d0=", 97 | "requires": { 98 | "long": "3.2.0" 99 | } 100 | }, 101 | "camelcase": { 102 | "version": "2.1.1", 103 | "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", 104 | "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" 105 | }, 106 | "caseless": { 107 | "version": "0.12.0", 108 | "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", 109 | "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=" 110 | }, 111 | "cliui": { 112 | "version": "3.2.0", 113 | "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", 114 | "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", 115 | "requires": { 116 | "string-width": "1.0.2", 117 | "strip-ansi": "3.0.1", 118 | "wrap-ansi": "2.1.0" 119 | } 120 | }, 121 | "co": { 122 | "version": "4.6.0", 123 | "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", 124 | "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" 125 | }, 126 | "code-point-at": { 127 | "version": "1.1.0", 128 | "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", 129 | "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" 130 | }, 131 | "colour": { 132 | "version": "0.7.1", 133 | "resolved": "https://registry.npmjs.org/colour/-/colour-0.7.1.tgz", 134 | "integrity": "sha1-nLFpkX7F0SwHNtPoaFdG3xyt93g=" 135 | }, 136 | "combined-stream": { 137 | "version": "1.0.5", 138 | "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", 139 | "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", 140 | "requires": { 141 | "delayed-stream": "1.0.0" 142 | } 143 | }, 144 | "concat-map": { 145 | "version": "0.0.1", 146 | "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", 147 | "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" 148 | }, 149 | "core-util-is": { 150 | "version": "1.0.2", 151 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 152 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 153 | }, 154 | "cryptiles": { 155 | "version": "3.1.2", 156 | "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz", 157 | "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=", 158 | "requires": { 159 | "boom": "5.2.0" 160 | }, 161 | "dependencies": { 162 | "boom": { 163 | "version": "5.2.0", 164 | "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", 165 | "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", 166 | "requires": { 167 | "hoek": "4.2.0" 168 | } 169 | } 170 | } 171 | }, 172 | "dashdash": { 173 | "version": "1.14.1", 174 | "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", 175 | "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", 176 | "requires": { 177 | "assert-plus": "1.0.0" 178 | } 179 | }, 180 | "debug": { 181 | "version": "2.6.9", 182 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 183 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 184 | "requires": { 185 | "ms": "2.0.0" 186 | } 187 | }, 188 | "decamelize": { 189 | "version": "1.2.0", 190 | "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", 191 | "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" 192 | }, 193 | "deep-equal": { 194 | "version": "1.0.1", 195 | "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", 196 | "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", 197 | "dev": true 198 | }, 199 | "deep-extend": { 200 | "version": "0.4.2", 201 | "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", 202 | "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=" 203 | }, 204 | "define-properties": { 205 | "version": "1.1.2", 206 | "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", 207 | "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", 208 | "dev": true, 209 | "requires": { 210 | "foreach": "2.0.5", 211 | "object-keys": "1.0.11" 212 | } 213 | }, 214 | "defined": { 215 | "version": "1.0.0", 216 | "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", 217 | "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", 218 | "dev": true 219 | }, 220 | "delayed-stream": { 221 | "version": "1.0.0", 222 | "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", 223 | "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" 224 | }, 225 | "ecc-jsbn": { 226 | "version": "0.1.1", 227 | "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", 228 | "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", 229 | "optional": true, 230 | "requires": { 231 | "jsbn": "0.1.1" 232 | } 233 | }, 234 | "es-abstract": { 235 | "version": "1.10.0", 236 | "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.10.0.tgz", 237 | "integrity": "sha512-/uh/DhdqIOSkAWifU+8nG78vlQxdLckUdI/sPgy0VhuXi2qJ7T8czBmqIYtLQVpCIFYafChnsRsB5pyb1JdmCQ==", 238 | "dev": true, 239 | "requires": { 240 | "es-to-primitive": "1.1.1", 241 | "function-bind": "1.1.1", 242 | "has": "1.0.1", 243 | "is-callable": "1.1.3", 244 | "is-regex": "1.0.4" 245 | } 246 | }, 247 | "es-to-primitive": { 248 | "version": "1.1.1", 249 | "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", 250 | "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", 251 | "dev": true, 252 | "requires": { 253 | "is-callable": "1.1.3", 254 | "is-date-object": "1.0.1", 255 | "is-symbol": "1.0.1" 256 | } 257 | }, 258 | "extend": { 259 | "version": "3.0.1", 260 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", 261 | "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=" 262 | }, 263 | "extsprintf": { 264 | "version": "1.3.0", 265 | "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", 266 | "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" 267 | }, 268 | "fast-deep-equal": { 269 | "version": "1.0.0", 270 | "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", 271 | "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=" 272 | }, 273 | "fast-json-stable-stringify": { 274 | "version": "2.0.0", 275 | "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", 276 | "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" 277 | }, 278 | "for-each": { 279 | "version": "0.3.2", 280 | "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.2.tgz", 281 | "integrity": "sha1-LEBFC5NI6X8oEyJZO6lnBLmr1NQ=", 282 | "dev": true, 283 | "requires": { 284 | "is-function": "1.0.1" 285 | } 286 | }, 287 | "foreach": { 288 | "version": "2.0.5", 289 | "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", 290 | "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", 291 | "dev": true 292 | }, 293 | "forever-agent": { 294 | "version": "0.6.1", 295 | "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", 296 | "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=" 297 | }, 298 | "form-data": { 299 | "version": "2.3.1", 300 | "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz", 301 | "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=", 302 | "requires": { 303 | "asynckit": "0.4.0", 304 | "combined-stream": "1.0.5", 305 | "mime-types": "2.1.17" 306 | } 307 | }, 308 | "fs.realpath": { 309 | "version": "1.0.0", 310 | "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", 311 | "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" 312 | }, 313 | "function-bind": { 314 | "version": "1.1.1", 315 | "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", 316 | "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", 317 | "dev": true 318 | }, 319 | "getpass": { 320 | "version": "0.1.7", 321 | "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", 322 | "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", 323 | "requires": { 324 | "assert-plus": "1.0.0" 325 | } 326 | }, 327 | "glob": { 328 | "version": "7.1.2", 329 | "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", 330 | "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", 331 | "requires": { 332 | "fs.realpath": "1.0.0", 333 | "inflight": "1.0.6", 334 | "inherits": "2.0.3", 335 | "minimatch": "3.0.4", 336 | "once": "1.4.0", 337 | "path-is-absolute": "1.0.1" 338 | } 339 | }, 340 | "google-play-proto": { 341 | "version": "1.3.1", 342 | "resolved": "https://registry.npmjs.org/google-play-proto/-/google-play-proto-1.3.1.tgz", 343 | "integrity": "sha512-a+4hSvr4YTIZ6RLl6iT1pEI1UZcCgY4g+bix4xMTbUr8PWpv3KuakZhdXEGKXlVRcubPh5uyU2n12ypDlp247w==" 344 | }, 345 | "gpapi": { 346 | "version": "4.4.1-0", 347 | "resolved": "https://registry.npmjs.org/gpapi/-/gpapi-4.4.1-0.tgz", 348 | "integrity": "sha512-LtZj3VVzbti5fyUqSBQlYQ57KfyP1vwCT2Cd101uYeWUN5IpR6C7OpfpJRvI33e/vcbUNc2sWYmGEiQydZ7N+Q==", 349 | "requires": { 350 | "bluebird": "3.5.1", 351 | "debug": "2.6.9", 352 | "google-play-proto": "1.3.1", 353 | "json-stable-stringify": "1.0.1", 354 | "lodash": "4.17.4", 355 | "protobufjs": "5.0.2", 356 | "request": "2.83.0", 357 | "request-debug": "0.2.0", 358 | "rsa-pem-from-mod-exp": "0.8.4", 359 | "split": "1.0.1", 360 | "through2": "2.0.3" 361 | } 362 | }, 363 | "har-schema": { 364 | "version": "2.0.0", 365 | "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", 366 | "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=" 367 | }, 368 | "har-validator": { 369 | "version": "5.0.3", 370 | "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", 371 | "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", 372 | "requires": { 373 | "ajv": "5.5.0", 374 | "har-schema": "2.0.0" 375 | } 376 | }, 377 | "has": { 378 | "version": "1.0.1", 379 | "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", 380 | "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", 381 | "dev": true, 382 | "requires": { 383 | "function-bind": "1.1.1" 384 | } 385 | }, 386 | "hawk": { 387 | "version": "6.0.2", 388 | "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz", 389 | "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==", 390 | "requires": { 391 | "boom": "4.3.1", 392 | "cryptiles": "3.1.2", 393 | "hoek": "4.2.0", 394 | "sntp": "2.1.0" 395 | } 396 | }, 397 | "hoek": { 398 | "version": "4.2.0", 399 | "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz", 400 | "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ==" 401 | }, 402 | "http-signature": { 403 | "version": "1.2.0", 404 | "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", 405 | "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", 406 | "requires": { 407 | "assert-plus": "1.0.0", 408 | "jsprim": "1.4.1", 409 | "sshpk": "1.13.1" 410 | } 411 | }, 412 | "inflight": { 413 | "version": "1.0.6", 414 | "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", 415 | "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", 416 | "requires": { 417 | "once": "1.4.0", 418 | "wrappy": "1.0.2" 419 | } 420 | }, 421 | "inherits": { 422 | "version": "2.0.3", 423 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", 424 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" 425 | }, 426 | "ini": { 427 | "version": "1.3.5", 428 | "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", 429 | "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" 430 | }, 431 | "invert-kv": { 432 | "version": "1.0.0", 433 | "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", 434 | "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" 435 | }, 436 | "is-callable": { 437 | "version": "1.1.3", 438 | "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", 439 | "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=", 440 | "dev": true 441 | }, 442 | "is-date-object": { 443 | "version": "1.0.1", 444 | "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", 445 | "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", 446 | "dev": true 447 | }, 448 | "is-fullwidth-code-point": { 449 | "version": "1.0.0", 450 | "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", 451 | "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", 452 | "requires": { 453 | "number-is-nan": "1.0.1" 454 | } 455 | }, 456 | "is-function": { 457 | "version": "1.0.1", 458 | "resolved": "https://registry.npmjs.org/is-function/-/is-function-1.0.1.tgz", 459 | "integrity": "sha1-Es+5i2W1fdPRk6MSH19uL0N2ArU=", 460 | "dev": true 461 | }, 462 | "is-regex": { 463 | "version": "1.0.4", 464 | "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", 465 | "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", 466 | "dev": true, 467 | "requires": { 468 | "has": "1.0.1" 469 | } 470 | }, 471 | "is-symbol": { 472 | "version": "1.0.1", 473 | "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", 474 | "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", 475 | "dev": true 476 | }, 477 | "is-typedarray": { 478 | "version": "1.0.0", 479 | "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", 480 | "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" 481 | }, 482 | "isarray": { 483 | "version": "1.0.0", 484 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 485 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 486 | }, 487 | "isstream": { 488 | "version": "0.1.2", 489 | "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", 490 | "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=" 491 | }, 492 | "jsbn": { 493 | "version": "0.1.1", 494 | "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", 495 | "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", 496 | "optional": true 497 | }, 498 | "json-schema": { 499 | "version": "0.2.3", 500 | "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", 501 | "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=" 502 | }, 503 | "json-schema-traverse": { 504 | "version": "0.3.1", 505 | "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", 506 | "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=" 507 | }, 508 | "json-stable-stringify": { 509 | "version": "1.0.1", 510 | "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", 511 | "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", 512 | "requires": { 513 | "jsonify": "0.0.0" 514 | } 515 | }, 516 | "json-stringify-safe": { 517 | "version": "5.0.1", 518 | "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", 519 | "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" 520 | }, 521 | "jsonify": { 522 | "version": "0.0.0", 523 | "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", 524 | "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=" 525 | }, 526 | "jsprim": { 527 | "version": "1.4.1", 528 | "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz", 529 | "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=", 530 | "requires": { 531 | "assert-plus": "1.0.0", 532 | "extsprintf": "1.3.0", 533 | "json-schema": "0.2.3", 534 | "verror": "1.10.0" 535 | } 536 | }, 537 | "lcid": { 538 | "version": "1.0.0", 539 | "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", 540 | "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", 541 | "requires": { 542 | "invert-kv": "1.0.0" 543 | } 544 | }, 545 | "lodash": { 546 | "version": "4.17.4", 547 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", 548 | "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=" 549 | }, 550 | "long": { 551 | "version": "3.2.0", 552 | "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", 553 | "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=" 554 | }, 555 | "mime-db": { 556 | "version": "1.30.0", 557 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz", 558 | "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE=" 559 | }, 560 | "mime-types": { 561 | "version": "2.1.17", 562 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz", 563 | "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=", 564 | "requires": { 565 | "mime-db": "1.30.0" 566 | } 567 | }, 568 | "minimatch": { 569 | "version": "3.0.4", 570 | "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", 571 | "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", 572 | "requires": { 573 | "brace-expansion": "1.1.8" 574 | } 575 | }, 576 | "minimist": { 577 | "version": "1.2.0", 578 | "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", 579 | "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" 580 | }, 581 | "ms": { 582 | "version": "2.0.0", 583 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 584 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 585 | }, 586 | "number-is-nan": { 587 | "version": "1.0.1", 588 | "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", 589 | "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" 590 | }, 591 | "oauth-sign": { 592 | "version": "0.8.2", 593 | "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", 594 | "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=" 595 | }, 596 | "object-inspect": { 597 | "version": "1.3.0", 598 | "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.3.0.tgz", 599 | "integrity": "sha512-OHHnLgLNXpM++GnJRyyhbr2bwl3pPVm4YvaraHrRvDt/N3r+s/gDVHciA7EJBTkijKXj61ssgSAikq1fb0IBRg==", 600 | "dev": true 601 | }, 602 | "object-keys": { 603 | "version": "1.0.11", 604 | "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", 605 | "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=", 606 | "dev": true 607 | }, 608 | "once": { 609 | "version": "1.4.0", 610 | "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", 611 | "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", 612 | "requires": { 613 | "wrappy": "1.0.2" 614 | } 615 | }, 616 | "optjs": { 617 | "version": "3.2.2", 618 | "resolved": "https://registry.npmjs.org/optjs/-/optjs-3.2.2.tgz", 619 | "integrity": "sha1-aabOicRCpEQDFBrS+bNwvVu29O4=" 620 | }, 621 | "os-locale": { 622 | "version": "1.4.0", 623 | "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", 624 | "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", 625 | "requires": { 626 | "lcid": "1.0.0" 627 | } 628 | }, 629 | "path-is-absolute": { 630 | "version": "1.0.1", 631 | "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", 632 | "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" 633 | }, 634 | "path-parse": { 635 | "version": "1.0.5", 636 | "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", 637 | "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", 638 | "dev": true 639 | }, 640 | "performance-now": { 641 | "version": "2.1.0", 642 | "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", 643 | "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" 644 | }, 645 | "process-nextick-args": { 646 | "version": "1.0.7", 647 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", 648 | "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=" 649 | }, 650 | "protobufjs": { 651 | "version": "5.0.2", 652 | "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-5.0.2.tgz", 653 | "integrity": "sha1-WXSNfc8D0tsiwT2p/rAk4Wq4DJE=", 654 | "requires": { 655 | "ascli": "1.0.1", 656 | "bytebuffer": "5.0.1", 657 | "glob": "7.1.2", 658 | "yargs": "3.32.0" 659 | } 660 | }, 661 | "punycode": { 662 | "version": "1.4.1", 663 | "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", 664 | "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" 665 | }, 666 | "qs": { 667 | "version": "6.5.1", 668 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", 669 | "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==" 670 | }, 671 | "rc": { 672 | "version": "1.2.2", 673 | "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.2.tgz", 674 | "integrity": "sha1-2M6ctX6NZNnHut2YdsfDTL48cHc=", 675 | "requires": { 676 | "deep-extend": "0.4.2", 677 | "ini": "1.3.5", 678 | "minimist": "1.2.0", 679 | "strip-json-comments": "2.0.1" 680 | } 681 | }, 682 | "readable-stream": { 683 | "version": "2.3.3", 684 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", 685 | "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", 686 | "requires": { 687 | "core-util-is": "1.0.2", 688 | "inherits": "2.0.3", 689 | "isarray": "1.0.0", 690 | "process-nextick-args": "1.0.7", 691 | "safe-buffer": "5.1.1", 692 | "string_decoder": "1.0.3", 693 | "util-deprecate": "1.0.2" 694 | } 695 | }, 696 | "request": { 697 | "version": "2.83.0", 698 | "resolved": "https://registry.npmjs.org/request/-/request-2.83.0.tgz", 699 | "integrity": "sha512-lR3gD69osqm6EYLk9wB/G1W/laGWjzH90t1vEa2xuxHD5KUrSzp9pUSfTm+YC5Nxt2T8nMPEvKlhbQayU7bgFw==", 700 | "requires": { 701 | "aws-sign2": "0.7.0", 702 | "aws4": "1.6.0", 703 | "caseless": "0.12.0", 704 | "combined-stream": "1.0.5", 705 | "extend": "3.0.1", 706 | "forever-agent": "0.6.1", 707 | "form-data": "2.3.1", 708 | "har-validator": "5.0.3", 709 | "hawk": "6.0.2", 710 | "http-signature": "1.2.0", 711 | "is-typedarray": "1.0.0", 712 | "isstream": "0.1.2", 713 | "json-stringify-safe": "5.0.1", 714 | "mime-types": "2.1.17", 715 | "oauth-sign": "0.8.2", 716 | "performance-now": "2.1.0", 717 | "qs": "6.5.1", 718 | "safe-buffer": "5.1.1", 719 | "stringstream": "0.0.5", 720 | "tough-cookie": "2.3.3", 721 | "tunnel-agent": "0.6.0", 722 | "uuid": "3.1.0" 723 | } 724 | }, 725 | "request-debug": { 726 | "version": "0.2.0", 727 | "resolved": "https://registry.npmjs.org/request-debug/-/request-debug-0.2.0.tgz", 728 | "integrity": "sha1-/AVOyBcYGwTKQaBSwTb2HEirr3g=", 729 | "requires": { 730 | "stringify-clone": "1.1.1" 731 | } 732 | }, 733 | "resolve": { 734 | "version": "1.4.0", 735 | "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", 736 | "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==", 737 | "dev": true, 738 | "requires": { 739 | "path-parse": "1.0.5" 740 | } 741 | }, 742 | "resumer": { 743 | "version": "0.0.0", 744 | "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", 745 | "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", 746 | "dev": true, 747 | "requires": { 748 | "through": "2.3.8" 749 | } 750 | }, 751 | "rsa-pem-from-mod-exp": { 752 | "version": "0.8.4", 753 | "resolved": "https://registry.npmjs.org/rsa-pem-from-mod-exp/-/rsa-pem-from-mod-exp-0.8.4.tgz", 754 | "integrity": "sha1-NipCxtMEBW1JOz8SvOq7LGV2ptQ=" 755 | }, 756 | "safe-buffer": { 757 | "version": "5.1.1", 758 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", 759 | "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" 760 | }, 761 | "sntp": { 762 | "version": "2.1.0", 763 | "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.1.0.tgz", 764 | "integrity": "sha512-FL1b58BDrqS3A11lJ0zEdnJ3UOKqVxawAkF3k7F0CVN7VQ34aZrV+G8BZ1WC9ZL7NyrwsW0oviwsWDgRuVYtJg==", 765 | "requires": { 766 | "hoek": "4.2.0" 767 | } 768 | }, 769 | "split": { 770 | "version": "1.0.1", 771 | "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", 772 | "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", 773 | "requires": { 774 | "through": "2.3.8" 775 | } 776 | }, 777 | "sshpk": { 778 | "version": "1.13.1", 779 | "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", 780 | "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", 781 | "requires": { 782 | "asn1": "0.2.3", 783 | "assert-plus": "1.0.0", 784 | "bcrypt-pbkdf": "1.0.1", 785 | "dashdash": "1.14.1", 786 | "ecc-jsbn": "0.1.1", 787 | "getpass": "0.1.7", 788 | "jsbn": "0.1.1", 789 | "tweetnacl": "0.14.5" 790 | } 791 | }, 792 | "string-width": { 793 | "version": "1.0.2", 794 | "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", 795 | "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", 796 | "requires": { 797 | "code-point-at": "1.1.0", 798 | "is-fullwidth-code-point": "1.0.0", 799 | "strip-ansi": "3.0.1" 800 | } 801 | }, 802 | "string.prototype.trim": { 803 | "version": "1.1.2", 804 | "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.1.2.tgz", 805 | "integrity": "sha1-0E3iyJ4Tf019IG8Ia17S+ua+jOo=", 806 | "dev": true, 807 | "requires": { 808 | "define-properties": "1.1.2", 809 | "es-abstract": "1.10.0", 810 | "function-bind": "1.1.1" 811 | } 812 | }, 813 | "string_decoder": { 814 | "version": "1.0.3", 815 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", 816 | "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", 817 | "requires": { 818 | "safe-buffer": "5.1.1" 819 | } 820 | }, 821 | "stringify-clone": { 822 | "version": "1.1.1", 823 | "resolved": "https://registry.npmjs.org/stringify-clone/-/stringify-clone-1.1.1.tgz", 824 | "integrity": "sha1-MJojX7Ts/M19OI2+GLqQT6yvQzs=" 825 | }, 826 | "stringstream": { 827 | "version": "0.0.5", 828 | "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", 829 | "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=" 830 | }, 831 | "strip-ansi": { 832 | "version": "3.0.1", 833 | "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", 834 | "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", 835 | "requires": { 836 | "ansi-regex": "2.1.1" 837 | } 838 | }, 839 | "strip-json-comments": { 840 | "version": "2.0.1", 841 | "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", 842 | "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=" 843 | }, 844 | "tape": { 845 | "version": "4.8.0", 846 | "resolved": "https://registry.npmjs.org/tape/-/tape-4.8.0.tgz", 847 | "integrity": "sha512-TWILfEnvO7I8mFe35d98F6T5fbLaEtbFTG/lxWvid8qDfFTxt19EBijWmB4j3+Hoh5TfHE2faWs73ua+EphuBA==", 848 | "dev": true, 849 | "requires": { 850 | "deep-equal": "1.0.1", 851 | "defined": "1.0.0", 852 | "for-each": "0.3.2", 853 | "function-bind": "1.1.1", 854 | "glob": "7.1.2", 855 | "has": "1.0.1", 856 | "inherits": "2.0.3", 857 | "minimist": "1.2.0", 858 | "object-inspect": "1.3.0", 859 | "resolve": "1.4.0", 860 | "resumer": "0.0.0", 861 | "string.prototype.trim": "1.1.2", 862 | "through": "2.3.8" 863 | } 864 | }, 865 | "through": { 866 | "version": "2.3.8", 867 | "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", 868 | "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" 869 | }, 870 | "through2": { 871 | "version": "2.0.3", 872 | "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", 873 | "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", 874 | "requires": { 875 | "readable-stream": "2.3.3", 876 | "xtend": "4.0.1" 877 | } 878 | }, 879 | "tough-cookie": { 880 | "version": "2.3.3", 881 | "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz", 882 | "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=", 883 | "requires": { 884 | "punycode": "1.4.1" 885 | } 886 | }, 887 | "tunnel-agent": { 888 | "version": "0.6.0", 889 | "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", 890 | "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", 891 | "requires": { 892 | "safe-buffer": "5.1.1" 893 | } 894 | }, 895 | "tweetnacl": { 896 | "version": "0.14.5", 897 | "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", 898 | "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", 899 | "optional": true 900 | }, 901 | "util-deprecate": { 902 | "version": "1.0.2", 903 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 904 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 905 | }, 906 | "uuid": { 907 | "version": "3.1.0", 908 | "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", 909 | "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==" 910 | }, 911 | "verror": { 912 | "version": "1.10.0", 913 | "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", 914 | "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", 915 | "requires": { 916 | "assert-plus": "1.0.0", 917 | "core-util-is": "1.0.2", 918 | "extsprintf": "1.3.0" 919 | } 920 | }, 921 | "window-size": { 922 | "version": "0.1.4", 923 | "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.4.tgz", 924 | "integrity": "sha1-+OGqHuWlPsW/FR/6CXQqatdpeHY=" 925 | }, 926 | "wrap-ansi": { 927 | "version": "2.1.0", 928 | "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", 929 | "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", 930 | "requires": { 931 | "string-width": "1.0.2", 932 | "strip-ansi": "3.0.1" 933 | } 934 | }, 935 | "wrappy": { 936 | "version": "1.0.2", 937 | "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", 938 | "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" 939 | }, 940 | "xtend": { 941 | "version": "4.0.1", 942 | "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", 943 | "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=" 944 | }, 945 | "y18n": { 946 | "version": "3.2.1", 947 | "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", 948 | "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" 949 | }, 950 | "yargs": { 951 | "version": "3.32.0", 952 | "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", 953 | "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", 954 | "requires": { 955 | "camelcase": "2.1.1", 956 | "cliui": "3.2.0", 957 | "decamelize": "1.2.0", 958 | "os-locale": "1.4.0", 959 | "string-width": "1.0.2", 960 | "window-size": "0.1.4", 961 | "y18n": "3.2.1" 962 | } 963 | } 964 | } 965 | } 966 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "google-play-cli", 3 | "version": "4.5.1-0", 4 | "description": "use google play mobile app APIs via CLI", 5 | "main": "index.js", 6 | "bin": { 7 | "gp-bulk-details": "bin/bulk-details", 8 | "gp-details": "bin/details", 9 | "gp-delivery": "bin/delivery", 10 | "gp-download": "bin/download", 11 | "gp-download-info": "bin/download-info", 12 | "gp-download-meta": "bin/download-meta", 13 | "gp-get-sha1": "bin/get-sha1", 14 | "gp-search": "bin/search", 15 | "gp-get-token": "bin/get-token" 16 | }, 17 | "preferGlobal": true, 18 | "scripts": { 19 | "test": "tape test/*.test.js" 20 | }, 21 | "repository": { 22 | "type": "git", 23 | "url": "https://github.com/dweinstein/node-google-play-cli.git" 24 | }, 25 | "keywords": [ 26 | "google", 27 | "play", 28 | "store", 29 | "cli", 30 | "download", 31 | "apk", 32 | "details", 33 | "bulk" 34 | ], 35 | "author": "dweinstein", 36 | "license": "MIT", 37 | "bugs": { 38 | "url": "https://github.com/dweinstein/node-google-play-cli/issues" 39 | }, 40 | "homepage": "https://github.com/dweinstein/node-google-play-cli", 41 | "dependencies": { 42 | "decamelize": "^1.2.0", 43 | "gpapi": "^4.4.1-0", 44 | "long": "^3.2.0", 45 | "minimist": "^1.1.1", 46 | "rc": "^1.1.6" 47 | }, 48 | "devDependencies": { 49 | "tape": "*" 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /test/scripts.test.js: -------------------------------------------------------------------------------- 1 | var test = require('tape'); 2 | var exec = require('child_process').exec; 3 | 4 | test('details', function (t) { 5 | var details = exec('./bin/details com.viber.voip', function (error, stdout, stderr) { 6 | t.notOk(error, 'should exit cleanly'); 7 | t.ok(stdout.length > 0, 'should produce some output'); 8 | t.doesNotThrow(JSON.parse.bind(null, stdout), 'parses json'); 9 | t.end(); 10 | }); 11 | }); 12 | 13 | test('bulkDetails', function (t) { 14 | var details = exec('./bin/bulk-details com.viber.voip air.WatchESPN', function (error, stdout, stderr) { 15 | t.notOk(error, 'should exit cleanly'); 16 | t.ok(stdout.length > 0, 'should produce some output'); 17 | t.doesNotThrow(JSON.parse.bind(null, stdout), 'parses json'); 18 | t.end(); 19 | }); 20 | }); 21 | 22 | test.skip('download', function (t) { 23 | var details = exec('./bin/download com.insitusec.isthisreallife > /dev/null', function (error, stdout, stderr) { 24 | t.notOk(error, 'should exit cleanly'); 25 | t.notOk(stderr, 'should not produce stderr'); 26 | t.end(); 27 | }); 28 | }); 29 | 30 | --------------------------------------------------------------------------------