diff --git a/.gitignore b/.gitignore deleted file mode 100644 index 186e71a..0000000 --- a/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -# build output -packed -download/dist - -# dependencies -node_modules - -# logs -npm-debug.log diff --git a/.npmrc b/.npmrc deleted file mode 100644 index 1dab4ed..0000000 --- a/.npmrc +++ /dev/null @@ -1 +0,0 @@ -save-exact = true diff --git a/bin/domains/buy.js b/bin/domains/buy.js deleted file mode 100644 index c3082d2..0000000 --- a/bin/domains/buy.js +++ /dev/null @@ -1,119 +0,0 @@ -const { italic, bold } = require('chalk') - -const error = require('../../lib/utils/output/error') -const wait = require('../../lib/utils/output/wait') -const cmd = require('../../lib/utils/output/cmd') -const param = require('../../lib/utils/output/param') -const info = require('../../lib/utils/output/info') -const success = require('../../lib/utils/output/success') -const stamp = require('../../lib/utils/output/stamp') -const promptBool = require('../../lib/utils/input/prompt-bool') -const eraseLines = require('../../lib/utils/output/erase-lines') -const treatBuyError = require('../../lib/utils/domains/treat-buy-error') -const NowCreditCards = require('../../lib/credit-cards') - -module.exports = async function({ domains, args, currentTeam, user, coupon }) { - const name = args[0] - let elapsed - - if (!name) { - return error(`Missing domain name. Run ${cmd('now domains help')}`) - } - - const nameParam = param(name) - let stopSpinner - - let price - let period - let validCoupon - try { - if (coupon) { - stopSpinner = wait(`Validating coupon ${param(coupon)}`) - const creditCards = new NowCreditCards({ - apiUrl: domains._agent._url, - token: domains._token, - debug: domains._debug, - currentTeam - }) - const [couponInfo, { cards }] = await Promise.all([ - domains.coupon(coupon), - creditCards.ls() - ]) - stopSpinner() - - if (!couponInfo.isValid) { - return error(`The coupon ${param(coupon)} is invalid`) - } - - if (!couponInfo.canBeUsed) { - return error(`The coupon ${param(coupon)} has already been used`) - } - - validCoupon = true - - if (cards.length === 0) { - info( - 'You have no credit cards on file. Please add one in order to claim your free domain' - ) - info(`Your card will ${bold('not')} be charged`) - - await require('../now-billing-add')({ - creditCards, - currentTeam, - user, - clear: true - }) - } - } - elapsed = stamp() - stopSpinner = wait(`Checking availability for ${nameParam}`) - const json = await domains.price(name) - price = validCoupon ? 0 : json.price - period = json.period - } catch (err) { - stopSpinner() - return error(err.message) - } - - const available = await domains.status(name) - - stopSpinner() - - if (!available) { - return error( - `The domain ${nameParam} is ${italic('unavailable')}! ${elapsed()}` - ) - } - const periodMsg = `${period}yr${period > 1 ? 's' : ''}` - info( - `The domain ${nameParam} is ${italic('available')} to buy under ${bold( - (currentTeam && currentTeam.slug) || user.username || user.email - )}! ${elapsed()}` - ) - const confirmation = await promptBool( - `Buy now for ${bold(`$${price}`)} (${periodMsg})?` - ) - - eraseLines(1) - if (!confirmation) { - return info('Aborted') - } - - stopSpinner = wait('Purchasing') - elapsed = stamp() - try { - await domains.buy({ name, coupon }) - } catch (err) { - stopSpinner() - return treatBuyError(err) - } - - stopSpinner() - - success(`Domain ${nameParam} purchased ${elapsed()}`) - info( - `You may now use your domain as an alias to your deployments. Run ${cmd( - 'now alias --help' - )}` - ) -} diff --git a/bin/now-alias.js b/bin/now-alias.js deleted file mode 100755 index 723b4c2..0000000 --- a/bin/now-alias.js +++ /dev/null @@ -1,529 +0,0 @@ -#!/usr/bin/env node - -// Packages -const chalk = require('chalk') -const minimist = require('minimist') -const table = require('text-table') -const ms = require('ms') -const printf = require('printf') -require('epipebomb')() -const supportsColor = require('supports-color') - -// Ours -const strlen = require('../lib/strlen') -const NowAlias = require('../lib/alias') -const NowDomains = require('../lib/domains') -const login = require('../lib/login') -const cfg = require('../lib/cfg') -const { handleError, error } = require('../lib/error') -const toHost = require('../lib/to-host') -const { reAlias } = require('../lib/re-alias') -const exit = require('../lib/utils/exit') -const info = require('../lib/utils/output/info') -const logo = require('../lib/utils/output/logo') -const promptBool = require('../lib/utils/input/prompt-bool') - -const argv = minimist(process.argv.slice(2), { - string: ['config', 'token', 'rules'], - boolean: ['help', 'debug'], - alias: { - help: 'h', - config: 'c', - rules: 'r', - debug: 'd', - token: 't' - } -}) - -const subcommand = argv._[0] - -const grayWidth = 10 -const underlineWidth = 11 - -// Options -const help = () => { - console.log(` - ${chalk.bold(`${logo} now alias`)} - - ${chalk.dim('Options:')} - - -h, --help Output usage information - -c ${chalk.bold.underline('FILE')}, --config=${chalk.bold.underline( - 'FILE' - )} Config file - -r ${chalk.bold.underline('RULES_FILE')}, --rules=${chalk.bold.underline( - 'RULES_FILE' - )} Rules file - -d, --debug Debug mode [off] - -t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline( - 'TOKEN' - )} Login token - - ${chalk.dim('Examples:')} - - ${chalk.gray('–')} Lists all your aliases: - - ${chalk.cyan('$ now alias ls')} - - ${chalk.gray('–')} Adds a new alias to ${chalk.underline('my-api.now.sh')}: - - ${chalk.cyan( - `$ now alias set ${chalk.underline( - 'api-ownv3nc9f8.now.sh' - )} ${chalk.underline('my-api.now.sh')}` - )} - - The ${chalk.dim('`.now.sh`')} suffix can be ommited: - - ${chalk.cyan('$ now alias set api-ownv3nc9f8 my-api')} - - The deployment id can be used as the source: - - ${chalk.cyan('$ now alias set deploymentId my-alias')} - - Custom domains work as alias targets: - - ${chalk.cyan( - `$ now alias set ${chalk.underline( - 'api-ownv3nc9f8.now.sh' - )} ${chalk.underline('my-api.com')}` - )} - - ${chalk.dim('–')} The subcommand ${chalk.dim( - '`set`' - )} is the default and can be skipped. - ${chalk.dim('–')} ${chalk.dim( - '`http(s)://`' - )} in the URLs is unneeded / ignored. - - ${chalk.gray('–')} Add and modify path based aliases for ${chalk.underline( - 'zeit.ninja' - )}: - - ${chalk.cyan( - `$ now alias ${chalk.underline('zeit.ninja')} -r ${chalk.underline( - 'rules.json' - )}` - )} - - Export effective routing rules: - - ${chalk.cyan( - `$ now alias ls aliasId --json > ${chalk.underline('rules.json')}` - )} - - ${chalk.cyan(`$ now alias ls zeit.ninja`)} - - ${chalk.gray('–')} Removing an alias: - - ${chalk.cyan('$ now alias rm aliasId')} - - To get the list of alias ids, use ${chalk.dim('`now alias ls`')}. - - ${chalk.dim('Alias:')} ln -`) -} - -// Options -const debug = argv.debug -const apiUrl = argv.url || 'https://api.zeit.co' - -if (argv.config) { - cfg.setConfigFile(argv.config) -} - -if (argv.help) { - help() - exit(0) -} else { - Promise.resolve() - .then(async () => { - const config = await cfg.read({ token: argv.token }) - - let token - try { - token = config.token || (await login(apiUrl)) - } catch (err) { - error(`Authentication error – ${err.message}`) - exit(1) - } - - try { - await run({ token, config }) - } catch (err) { - if (err.userError) { - error(err.message) - } else { - error(`Unknown error: ${err}\n${err.stack}`) - } - exit(1) - } - }) - .catch(err => { - handleError(err) - process.exit(1) - }) -} - -async function run({ token, config: { currentTeam, user } }) { - const alias = new NowAlias({ apiUrl, token, debug, currentTeam }) - const domains = new NowDomains({ apiUrl, token, debug, currentTeam }) - const args = argv._.slice(1) - - switch (subcommand) { - case 'ls': - case 'list': { - if (args.length === 1) { - const list = await alias.listAliases() - const item = list.find( - e => e.uid === argv._[1] || e.alias === argv._[1] - ) - if (!item || !item.rules) { - error(`Could not match path alias for: ${argv._[1]}`) - return exit(1) - } - - if (argv.json) { - console.log(JSON.stringify({ rules: item.rules }, null, 2)) - } else { - const header = [ - ['', 'pathname', 'method', 'dest'].map(s => chalk.dim(s)) - ] - const text = - list.length === 0 - ? null - : table( - header.concat( - item.rules.map(rule => { - return [ - '', - rule.pathname ? rule.pathname : '', - rule.method ? rule.method : '*', - rule.dest - ] - }) - ), - { - align: ['l', 'l', 'l', 'l'], - hsep: ' '.repeat(2), - stringLength: strlen - } - ) - - console.log(text) - } - break - } else if (args.length !== 0) { - error( - `Invalid number of arguments. Usage: ${chalk.cyan('`now alias ls`')}` - ) - return exit(1) - } - - const start_ = new Date() - const aliases = await alias.ls() - aliases.sort((a, b) => new Date(b.created) - new Date(a.created)) - const current = new Date() - const sourceUrlLength = - aliases.reduce((acc, i) => { - return Math.max(acc, (i.deployment && i.deployment.url.length) || 0) - }, 0) + 9 - const aliasLength = - aliases.reduce((acc, i) => { - return Math.max(acc, (i.alias && i.alias.length) || 0) - }, 0) + 8 - const elapsed_ = ms(new Date() - start_) - console.log( - `> ${aliases.length} alias${aliases.length === 1 - ? '' - : 'es'} found ${chalk.gray(`[${elapsed_}]`)} under ${chalk.bold( - (currentTeam && currentTeam.slug) || user.username || user.email - )}` - ) - console.log() - - if (supportsColor) { - const urlSpecHeader = `%-${sourceUrlLength + 1}s` - const aliasSpecHeader = `%-${aliasLength + 1}s` - console.log( - printf( - ` ${chalk.gray(urlSpecHeader + ' ' + aliasSpecHeader + ' %5s')}`, - 'source', - 'url', - 'age' - ) - ) - } else { - const urlSpecHeader = `%-${sourceUrlLength}s` - const aliasSpecHeader = `%-${aliasLength}s` - console.log( - printf( - ` ${urlSpecHeader} ${aliasSpecHeader} %5s`, - 'source', - 'url', - 'age' - ) - ) - } - - let text = '' - aliases.forEach(_alias => { - let urlSpec = sourceUrlLength - let aliasSpec = aliasLength - let ageSpec = 5 - const _url = chalk.underline(_alias.alias) - let _sourceUrl - if (supportsColor) { - aliasSpec += underlineWidth - ageSpec += grayWidth - } - if (_alias.deployment) { - _sourceUrl = chalk.underline(_alias.deployment.url) - if (supportsColor) { - urlSpec += grayWidth - } - } else if (_alias.rules) { - _sourceUrl = chalk.gray( - `[${_alias.rules.length} custom rule${_alias.rules.length > 1 - ? 's' - : ''}]` - ) - if (supportsColor) { - urlSpec += underlineWidth - } - } else { - _sourceUrl = chalk.gray('') - } - - const time = chalk.gray(ms(current - new Date(_alias.created))) - text += printf( - ` %-${urlSpec}s %-${aliasSpec}s %${ageSpec}s\n`, - _sourceUrl, - _url, - time - ) - }) - - console.log(text) - break - } - case 'rm': - case 'remove': { - const _target = String(args[0]) - if (!_target) { - const err = new Error('No alias id specified') - err.userError = true - throw err - } - - if (args.length !== 1) { - error( - `Invalid number of arguments. Usage: ${chalk.cyan( - '`now alias rm `' - )}` - ) - return exit(1) - } - - const _aliases = await alias.ls() - const _alias = findAlias(_target, _aliases) - - if (!_alias) { - const err = new Error( - `Alias not found by "${_target}" under ${chalk.bold( - (currentTeam && currentTeam.slug) || user.username || user.email - )}. Run ${chalk.dim('`now alias ls`')} to see your aliases.` - ) - err.userError = true - throw err - } - - try { - const confirmation = await confirmDeploymentRemoval(alias, _alias) - if (!confirmation) { - info('Aborted') - return process.exit(0) - } - - const start = new Date() - await alias.rm(_alias) - const elapsed = ms(new Date() - start) - console.log( - `${chalk.cyan('> Success!')} Alias ${chalk.bold( - _alias.uid - )} removed [${elapsed}]` - ) - } catch (err) { - error(err) - exit(1) - } - - break - } - case 'add': - case 'set': { - if (argv.rules) { - await updatePathAlias(alias, argv._[0], argv.rules, domains) - break - } - if (args.length !== 2) { - error( - `Invalid number of arguments. Usage: ${chalk.cyan( - '`now alias set `' - )}` - ) - return exit(1) - } - await alias.set( - String(args[0]), - String(args[1]), - domains, - currentTeam, - user - ) - break - } - default: { - if (argv._.length === 0) { - await reAlias( - token, - null, - null, - help, - exit, - apiUrl, - debug, - alias, - currentTeam, - user - ) - break - } - - if (argv.rules) { - await updatePathAlias(alias, argv._[0], argv.rules, domains) - break - } - - if (argv._.length === 1) { - await reAlias( - token, - null, - String(argv._[0]), - help, - exit, - apiUrl, - debug, - alias, - currentTeam, - user - ) - break - } else if (argv._.length === 2) { - await alias.set( - String(argv._[0]), - String(argv._[1]), - domains, - currentTeam, - user - ) - } else if (argv._.length >= 3) { - error('Invalid number of arguments') - help() - exit(1) - } else { - error('Please specify a valid subcommand: ls | set | rm') - help() - exit(1) - } - } - } - - domains.close() - alias.close() -} - -async function confirmDeploymentRemoval(alias, _alias) { - const time = chalk.gray(ms(new Date() - new Date(_alias.created)) + ' ago') - const _sourceUrl = _alias.deployment - ? chalk.underline(_alias.deployment.url) - : null - const tbl = table( - [ - [ - _alias.uid, - ...(_sourceUrl ? [_sourceUrl] : []), - chalk.underline(_alias.alias), - time - ] - ], - { hsep: ' '.repeat(6) } - ) - - const msg = - '> The following alias will be removed permanently\n' + - ` ${tbl} \nAre you sure?` - - return promptBool(msg, { - trailing: '\n' - }) -} - -function findAlias(alias, list) { - let key - let val - - if (/\./.test(alias)) { - val = toHost(alias) - key = 'alias' - } else { - val = alias - key = 'uid' - } - - const _alias = list.find(d => { - if (d[key] === val) { - if (debug) { - console.log(`> [debug] matched alias ${d.uid} by ${key} ${val}`) - } - - return true - } - - // Match prefix - if (`${val}.now.sh` === d.alias) { - if (debug) { - console.log(`> [debug] matched alias ${d.uid} by url ${d.host}`) - } - - return true - } - - return false - }) - - return _alias -} - -async function updatePathAlias(alias, aliasName, rules, domains) { - const start = new Date() - const res = await alias.updatePathBasedroutes( - String(aliasName), - rules, - domains - ) - const elapsed = ms(new Date() - start) - if (res.error) { - const err = new Error(res.error.message) - err.userError = true - throw err - } else { - console.log( - `${chalk.cyan( - '> Success!' - )} ${res.ruleCount} rules configured for ${chalk.underline( - res.alias - )} [${elapsed}]` - ) - } -} diff --git a/bin/now-billing-add.js b/bin/now-billing-add.js deleted file mode 100644 index c1068dd..0000000 --- a/bin/now-billing-add.js +++ /dev/null @@ -1,255 +0,0 @@ -#!/usr/bin/env node - -// Packages -const ansiEscapes = require('ansi-escapes') -const chalk = require('chalk') -const ccValidator = require('credit-card') - -// Ours -const textInput = require('../lib/utils/input/text') -const countries = require('../lib/utils/billing/country-list') -const cardBrands = require('../lib/utils/billing/card-brands') -const geocode = require('../lib/utils/billing/geocode') -const success = require('../lib/utils/output/success') -const wait = require('../lib/utils/output/wait') -const { tick } = require('../lib/utils/output/chars') -const rightPad = require('../lib/utils/output/right-pad') - -function expDateMiddleware(data) { - return data -} - -module.exports = async function({ - creditCards, - currentTeam, - user, - clear = false -}) { - const state = { - error: undefined, - cardGroupLabel: `> ${chalk.bold( - `Enter your card details for ${chalk.bold( - (currentTeam && currentTeam.slug) || user.username || user.email - )}` - )}`, - - name: { - label: rightPad('Full Name', 12), - placeholder: 'John Appleseed', - validateValue: data => data.trim().length > 0 - }, - - cardNumber: { - label: rightPad('Number', 12), - mask: 'cc', - placeholder: '#### #### #### ####', - validateKeypress: (data, value) => /\d/.test(data) && value.length < 19, - validateValue: data => { - data = data.replace(/ /g, '') - const type = ccValidator.determineCardType(data) - if (!type) { - return false - } - return ccValidator.isValidCardNumber(data, type) - } - }, - - ccv: { - label: rightPad('CCV', 12), - mask: 'ccv', - placeholder: '###', - validateValue: data => { - const brand = state.cardNumber.brand.toLowerCase() - return ccValidator.doesCvvMatchType(data, brand) - } - }, - - expDate: { - label: rightPad('Exp. Date', 12), - mask: 'expDate', - placeholder: 'mm / yyyy', - middleware: expDateMiddleware, - validateValue: data => !ccValidator.isExpired(...data.split(' / ')) - }, - - addressGroupLabel: `\n> ${chalk.bold('Enter your billing address')}`, - - country: { - label: rightPad('Country', 12), - async autoComplete(value) { - for (const country in countries) { - if (!Object.hasOwnProperty.call(countries, country)) { - continue - } - - if (country.startsWith(value)) { - return country.substr(value.length) - } - - const lowercaseCountry = country.toLowerCase() - const lowercaseValue = value.toLowerCase() - - if (lowercaseCountry.startsWith(lowercaseValue)) { - return lowercaseCountry.substr(value.length) - } - } - - return false - }, - validateValue: value => { - for (const country in countries) { - if (!Object.hasOwnProperty.call(countries, country)) { - continue - } - - if (country.toLowerCase() === value.toLowerCase()) { - return true - } - } - - return false - } - }, - - zipCode: { - label: rightPad('ZIP', 12), - validadeKeypress: data => data.trim().length > 0, - validateValue: data => data.trim().length > 0 - }, - - state: { - label: rightPad('State', 12), - validateValue: data => data.trim().length > 0 - }, - - city: { - label: rightPad('City', 12), - validateValue: data => data.trim().length > 0 - }, - - address1: { - label: rightPad('Address', 12), - validateValue: data => data.trim().length > 0 - } - } - - async function render() { - for (const key in state) { - if (!Object.hasOwnProperty.call(state, key)) { - continue - } - const piece = state[key] - if (typeof piece === 'string') { - console.log(piece) - } else if (typeof piece === 'object') { - let result - try { - /* eslint-disable no-await-in-loop */ - result = await textInput({ - label: '- ' + piece.label, - initialValue: piece.initialValue || piece.value, - placeholder: piece.placeholder, - mask: piece.mask, - validateKeypress: piece.validateKeypress, - validateValue: piece.validateValue, - autoComplete: piece.autoComplete - }) - - piece.value = result - - if (key === 'cardNumber') { - let brand = cardBrands[ccValidator.determineCardType(result)] - piece.brand = brand - - if (brand === 'American Express') { - state.ccv.placeholder = '#'.repeat(4) - } else { - state.ccv.placeholder = '#'.repeat(3) - } - - brand = chalk.cyan(`[${brand}]`) - const masked = chalk.gray('#### '.repeat(3)) + result.split(' ')[3] - process.stdout.write( - `${chalk.cyan(tick)} ${piece.label}${masked} ${brand}\n` - ) - } else if (key === 'ccv') { - process.stdout.write( - `${chalk.cyan(tick)} ${piece.label}${'*'.repeat(result.length)}\n` - ) - } else if (key === 'expDate') { - let text = result.split(' / ') - text = text[0] + chalk.gray(' / ') + text[1] - process.stdout.write(`${chalk.cyan(tick)} ${piece.label}${text}\n`) - } else if (key === 'zipCode') { - const stopSpinner = wait(piece.label + result) - const addressInfo = await geocode({ - country: state.country.value, - zipCode: result - }) - if (addressInfo.state) { - state.state.initialValue = addressInfo.state - } - if (addressInfo.city) { - state.city.initialValue = addressInfo.city - } - stopSpinner() - process.stdout.write( - `${chalk.cyan(tick)} ${piece.label}${result}\n` - ) - } else { - process.stdout.write( - `${chalk.cyan(tick)} ${piece.label}${result}\n` - ) - } - } catch (err) { - if (err.message === 'USER_ABORT') { - process.exit(1) - } else { - console.error(err) - } - } - } - } - console.log('') // New line - const stopSpinner = wait('Saving card') - - try { - const res = await creditCards.add({ - name: state.name.value, - cardNumber: state.cardNumber.value, - ccv: state.ccv.value, - expDate: state.expDate.value, - country: state.country.value, - zipCode: state.zipCode.value, - state: state.state.value, - city: state.city.value, - address1: state.address1.value - }) - stopSpinner() - if (clear) { - const linesToClear = state.error ? 15 : 14 - process.stdout.write(ansiEscapes.eraseLines(linesToClear)) - } - success( - `${state.cardNumber - .brand} ending in ${res.last4} was added to ${chalk.bold( - (currentTeam && currentTeam.slug) || user.username || user.email - )}` - ) - } catch (err) { - stopSpinner() - const linesToClear = state.error ? 15 : 14 - process.stdout.write(ansiEscapes.eraseLines(linesToClear)) - state.error = `${chalk.red( - '> Error!' - )} ${err.message} Please make sure the info is correct` - await render() - } - } - - try { - await render() - } catch (err) { - console.erorr(err) - } -} diff --git a/bin/now-billing.js b/bin/now-billing.js deleted file mode 100644 index 4d69535..0000000 --- a/bin/now-billing.js +++ /dev/null @@ -1,381 +0,0 @@ -#!/usr/bin/env node - -// Native -const { resolve } = require('path') - -// Packages -const chalk = require('chalk') -const minimist = require('minimist') -const ms = require('ms') - -// Ours -const login = require('../lib/login') -const cfg = require('../lib/cfg') -const { handleError, error } = require('../lib/error') -const NowCreditCards = require('../lib/credit-cards') -const indent = require('../lib/indent') -const listInput = require('../lib/utils/input/list') -const success = require('../lib/utils/output/success') -const promptBool = require('../lib/utils/input/prompt-bool') -const info = require('../lib/utils/output/info') -const logo = require('../lib/utils/output/logo') - -const argv = minimist(process.argv.slice(2), { - string: ['config', 'token'], - boolean: ['help', 'debug'], - alias: { - help: 'h', - config: 'c', - debug: 'd', - token: 't' - } -}) - -const subcommand = argv._[0] - -const help = () => { - console.log(` - ${chalk.bold(`${logo} now billing`)} - - ${chalk.dim('Options:')} - - -h, --help Output usage information - -c ${chalk.bold.underline('FILE')}, --config=${chalk.bold.underline( - 'FILE' - )} Config file - -d, --debug Debug mode [off] - -t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline( - 'TOKEN' - )} Login token - - ${chalk.dim('Examples:')} - - ${chalk.gray('–')} Lists all your credit cards: - - ${chalk.cyan('$ now billing ls')} - - ${chalk.gray('–')} Adds a credit card (interactively): - - ${chalk.cyan(`$ now billing add`)} - - ${chalk.gray('–')} Removes a credit card: - - ${chalk.cyan(`$ now billing rm `)} - - ${chalk.gray('–')} If the id is omitted, you can choose interactively - - ${chalk.gray('–')} Selects your default credit card: - - ${chalk.cyan(`$ now billing set-default `)} - - ${chalk.gray('–')} If the id is omitted, you can choose interactively - `) -} - -// Options -const debug = argv.debug -const apiUrl = argv.url || 'https://api.zeit.co' - -if (argv.config) { - cfg.setConfigFile(argv.config) -} - -const exit = code => { - // We give stdout some time to flush out - // because there's a node bug where - // stdout writes are asynchronous - // https://github.com/nodejs/node/issues/6456 - setTimeout(() => process.exit(code || 0), 100) -} - -if (argv.help || !subcommand) { - help() - exit(0) -} else { - Promise.resolve() - .then(async () => { - const config = await cfg.read({ token: argv.token }) - - let token - try { - token = config.token || (await login(apiUrl)) - } catch (err) { - error(`Authentication error – ${err.message}`) - exit(1) - } - try { - await run({ token, config }) - } catch (err) { - if (err.userError) { - error(err.message) - } else { - error(`Unknown error: ${err.stack}`) - } - exit(1) - } - }) - .catch(err => { - handleError(err) - process.exit(1) - }) -} - -// Builds a `choices` object that can be passesd to inquirer.prompt() -function buildInquirerChoices(cards) { - return cards.cards.map(card => { - const _default = - card.id === cards.defaultCardId ? ' ' + chalk.bold('(default)') : '' - const id = `${chalk.cyan(`ID: ${card.id}`)}${_default}` - const number = `${chalk.gray('#### ').repeat(3)}${card.last4}` - const str = [ - id, - indent(card.name, 2), - indent(`${card.brand} ${number}`, 2) - ].join('\n') - - return { - name: str, // Will be displayed by Inquirer - value: card.id, // Will be used to identify the answer - short: card.id // Will be displayed after the users answers - } - }) -} - -async function run({ token, config: { currentTeam, user } }) { - const start = new Date() - const creditCards = new NowCreditCards({ apiUrl, token, debug, currentTeam }) - const args = argv._.slice(1) - - switch (subcommand) { - case 'ls': - case 'list': { - let cards - try { - cards = await creditCards.ls() - } catch (err) { - error(err.message) - return - } - const text = cards.cards - .map(card => { - const _default = - card.id === cards.defaultCardId ? ' ' + chalk.bold('(default)') : '' - const id = `${chalk.gray('-')} ${chalk.cyan( - `ID: ${card.id}` - )}${_default}` - const number = `${chalk.gray('#### ').repeat(3)}${card.last4}` - let address = card.address_line1 - - if (card.address_line2) { - address += `, ${card.address_line2}.` - } else { - address += '.' - } - - address += `\n${card.address_city}, ` - - if (card.address_state) { - address += `${card.address_state}, ` - } - - // Stripe is returning a two digit code for the country, - // but we want the full country name - address += `${card.address_zip}. ${card.address_country}` - - return [ - id, - indent(card.name, 2), - indent(`${card.brand} ${number}`, 2), - indent(address, 2) - ].join('\n') - }) - .join('\n\n') - - const elapsed = ms(new Date() - start) - console.log( - `> ${cards.cards.length} card${cards.cards.length === 1 - ? '' - : 's'} found under ${chalk.bold( - (currentTeam && currentTeam.slug) || user.username || user.email - )} ${chalk.gray(`[${elapsed}]`)}` - ) - if (text) { - console.log(`\n${text}\n`) - } - - break - } - - case 'set-default': { - if (args.length > 1) { - error('Invalid number of arguments') - return exit(1) - } - - const start = new Date() - - let cards - try { - cards = await creditCards.ls() - } catch (err) { - error(err.message) - return - } - - if (cards.cards.length === 0) { - error('You have no credit cards to choose from') - return exit(0) - } - - let cardId = args[0] - - if (cardId === undefined) { - const elapsed = ms(new Date() - start) - const message = `Selecting a new default payment card for ${chalk.bold( - (currentTeam && currentTeam.slug) || user.username || user.email - )} ${chalk.gray(`[${elapsed}]`)}` - const choices = buildInquirerChoices(cards) - - cardId = await listInput({ - message, - choices, - separator: true, - abort: 'end' - }) - } - - // Check if the provided cardId (in case the user - // typed `now billing set-default `) is valid - if (cardId) { - const label = `Are you sure that you to set this card as the default?` - const confirmation = await promptBool(label, { - trailing: '\n' - }) - if (!confirmation) { - info('Aborted') - break - } - const start = new Date() - await creditCards.setDefault(cardId) - - const card = cards.cards.find(card => card.id === cardId) - const elapsed = ms(new Date() - start) - success( - `${card.brand} ending in ${card.last4} is now the default ${chalk.gray( - `[${elapsed}]` - )}` - ) - } else { - console.log('No changes made') - } - - break - } - - case 'rm': - case 'remove': { - if (args.length > 1) { - error('Invalid number of arguments') - return exit(1) - } - - const start = new Date() - let cards - try { - cards = await creditCards.ls() - } catch (err) { - error(err.message) - return - } - - if (cards.cards.length === 0) { - error( - `You have no credit cards to choose from to delete under ${chalk.bold( - (currentTeam && currentTeam.slug) || user.username || user.email - )}` - ) - return exit(0) - } - - let cardId = args[0] - - if (cardId === undefined) { - const elapsed = ms(new Date() - start) - const message = `Selecting a card to ${chalk.underline( - 'remove' - )} under ${chalk.bold( - (currentTeam && currentTeam.slug) || user.username || user.email - )} ${chalk.gray(`[${elapsed}]`)}` - const choices = buildInquirerChoices(cards) - - cardId = await listInput({ - message, - choices, - separator: true, - abort: 'start' - }) - } - - // Shoud check if the provided cardId (in case the user - // typed `now billing rm `) is valid - if (cardId) { - const label = `Are you sure that you want to remove this card?` - const confirmation = await promptBool(label) - if (!confirmation) { - console.log('Aborted') - break - } - const start = new Date() - await creditCards.rm(cardId) - - const deletedCard = cards.cards.find(card => card.id === cardId) - const remainingCards = cards.cards.filter(card => card.id !== cardId) - - let text = `${deletedCard.brand} ending in ${deletedCard.last4} was deleted` - // ${chalk.gray(`[${elapsed}]`)} - - if (cardId === cards.defaultCardId) { - if (remainingCards.length === 0) { - // The user deleted the last card in their account - text += `\n${chalk.yellow('Warning!')} You have no default card` - } else { - // We can't guess the current default card – let's ask the API - const cards = await creditCards.ls() - const newDefaultCard = cards.cards.find( - card => card.id === cards.defaultCardId - ) - - text += `\n${newDefaultCard.brand} ending in ${newDefaultCard.last4} in now default for ${chalk.bold( - (currentTeam && currentTeam.slug) || user.username || user.email - )}` - } - } - - const elapsed = ms(new Date() - start) - text += ` ${chalk.gray(`[${elapsed}]`)}` - success(text) - } else { - console.log('No changes made') - } - - break - } - - case 'add': { - require(resolve(__dirname, 'now-billing-add.js'))({ - creditCards, - currentTeam, - user - }) - - break - } - - default: - error('Please specify a valid subcommand: ls | add | rm | set-default') - help() - exit(1) - } - - creditCards.close() -} diff --git a/bin/now-certs.js b/bin/now-certs.js deleted file mode 100755 index 343bdce..0000000 --- a/bin/now-certs.js +++ /dev/null @@ -1,384 +0,0 @@ -#!/usr/bin/env node - -// Native -const path = require('path') - -// Packages -const chalk = require('chalk') -const table = require('text-table') -const minimist = require('minimist') -const fs = require('fs-extra') -const ms = require('ms') -const printf = require('printf') -require('epipebomb')() -const supportsColor = require('supports-color') - -// Ours -const cfg = require('../lib/cfg') -const { handleError, error } = require('../lib/error') -const NowCerts = require('../lib/certs') -const login = require('../lib/login') -const exit = require('../lib/utils/exit') -const logo = require('../lib/utils/output/logo') - -const argv = minimist(process.argv.slice(2), { - string: ['config', 'token', 'crt', 'key', 'ca'], - boolean: ['help', 'debug'], - alias: { help: 'h', config: 'c', debug: 'd', token: 't' } -}) - -const subcommand = argv._[0] - -// Options -const help = () => { - console.log(` - ${chalk.bold(`${logo} now certs`)} - - ${chalk.dim('Note:')} - - This command is intended for advanced use only, normally ${chalk.bold( - 'now' - )} manages your certificates automatically. - - ${chalk.dim('Options:')} - - -h, --help Output usage information - -c ${chalk.bold.underline('FILE')}, --config=${chalk.bold.underline( - 'FILE' - )} Config file - -d, --debug Debug mode [off] - -t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline( - 'TOKEN' - )} Login token - --crt ${chalk.bold.underline('FILE')} Certificate file - --key ${chalk.bold.underline('FILE')} Certificate key file - --ca ${chalk.bold.underline('FILE')} CA certificate chain file - - ${chalk.dim('Examples:')} - - ${chalk.gray('–')} Listing all your certificates: - - ${chalk.cyan('$ now certs ls')} - - ${chalk.gray('–')} Creating a new certificate: - - ${chalk.cyan('$ now certs create domain.com')} - - ${chalk.gray('–')} Renewing an existing certificate issued with ${chalk.bold( - 'now' - )}: - - ${chalk.cyan('$ now certs renew domain.com')} - - ${chalk.gray( - '–' - )} Replacing an existing certificate with a user-supplied certificate: - - ${chalk.cyan( - '$ now certs replace --crt domain.crt --key domain.key --ca ca_chain.crt domain.com' - )} -`) -} - -// Options -const debug = argv.debug -const apiUrl = argv.url || 'https://api.zeit.co' - -if (argv.config) { - cfg.setConfigFile(argv.config) -} - -if (argv.help || !subcommand) { - help() - exit(0) -} else { - Promise.resolve() - .then(async () => { - const config = await cfg.read({ token: argv.token }) - - let token - try { - token = config.token || (await login(apiUrl)) - } catch (err) { - error(`Authentication error – ${err.message}`) - exit(1) - } - - try { - await run({ token, config }) - } catch (err) { - handleError(err) - exit(1) - } - }) - .catch(err => { - handleError(err) - process.exit(1) - }) -} - -function formatExpirationDate(date) { - const diff = date - Date.now() - return diff < 0 - ? chalk.gray(ms(-diff) + ' ago') - : chalk.gray('in ' + ms(diff)) -} - -async function run({ token, config: { currentTeam, user } }) { - const certs = new NowCerts({ apiUrl, token, debug, currentTeam }) - const args = argv._.slice(1) - const start = Date.now() - - if (subcommand === 'ls' || subcommand === 'list') { - if (args.length !== 0) { - error( - `Invalid number of arguments. Usage: ${chalk.cyan('`now certs ls`')}` - ) - return exit(1) - } - - const list = await certs.ls() - const elapsed = ms(new Date() - start) - - console.log( - `> ${list.length} certificate${list.length === 1 - ? '' - : 's'} found ${chalk.gray(`[${elapsed}]`)} under ${chalk.bold( - (currentTeam && currentTeam.slug) || user.username || user.email - )}` - ) - - if (list.length > 0) { - const cur = Date.now() - list.sort((a, b) => { - return a.cn.localeCompare(b.cn) - }) - - const maxCnLength = - list.reduce((acc, i) => { - return Math.max(acc, (i.cn && i.cn.length) || 0) - }, 0) + 1 - - console.log( - chalk.dim( - printf( - ` %-${maxCnLength}s %-8s %-10s %-10s`, - 'cn', - 'created', - 'expiration', - 'auto-renew' - ) - ) - ) - - list.forEach(cert => { - const cn = chalk.bold(cert.cn) - const time = chalk.gray(ms(cur - new Date(cert.created)) + ' ago') - const expiration = formatExpirationDate(new Date(cert.expiration)) - const autoRenew = cert.autoRenew ? 'yes' : 'no' - let spec - if (supportsColor) { - spec = ` %-${maxCnLength + 9}s %-18s %-20s %-20s\n` - } else { - spec = ` %-${maxCnLength}s %-8s %-10s %-10s\n` - } - process.stdout.write(printf(spec, cn, time, expiration, autoRenew)) - }) - } - } else if (subcommand === 'create') { - if (args.length !== 1) { - error( - `Invalid number of arguments. Usage: ${chalk.cyan( - '`now certs create `' - )}` - ) - return exit(1) - } - const cn = args[0] - let cert - - if (argv.crt || argv.key || argv.ca) { - // Issue a custom certificate - if (!argv.crt || !argv.key) { - error( - `Missing required arguments for a custom certificate entry. Usage: ${chalk.cyan( - '`now certs create --crt DOMAIN.CRT --key DOMAIN.KEY [--ca CA.CRT] `' - )}` - ) - return exit(1) - } - - const crt = readX509File(argv.crt) - const key = readX509File(argv.key) - const ca = argv.ca ? readX509File(argv.ca) : '' - - cert = await certs.put(cn, crt, key, ca) - } else { - // Issue a standard certificate - cert = await certs.create(cn) - } - if (!cert) { - // Cert is undefined and "Cert is already issued" has been printed to stdout - return exit(1) - } - const elapsed = ms(new Date() - start) - console.log( - `${chalk.cyan('> Success!')} Certificate entry ${chalk.bold( - cn - )} ${chalk.gray(`(${cert.uid})`)} created ${chalk.gray(`[${elapsed}]`)}` - ) - } else if (subcommand === 'renew') { - if (args.length !== 1) { - error( - `Invalid number of arguments. Usage: ${chalk.cyan( - '`now certs renew `' - )}` - ) - return exit(1) - } - - const cert = await getCertIdCn(certs, args[0], currentTeam, user) - if (!cert) { - return exit(1) - } - const yes = await readConfirmation( - cert, - 'The following certificate will be renewed\n' - ) - - if (!yes) { - error('User abort') - return exit(0) - } - - await certs.renew(cert.cn) - const elapsed = ms(new Date() - start) - console.log( - `${chalk.cyan('> Success!')} Certificate ${chalk.bold( - cert.cn - )} ${chalk.gray(`(${cert.uid})`)} renewed ${chalk.gray(`[${elapsed}]`)}` - ) - } else if (subcommand === 'replace') { - if (!argv.crt || !argv.key) { - error( - `Invalid number of arguments. Usage: ${chalk.cyan( - '`now certs replace --crt DOMAIN.CRT --key DOMAIN.KEY [--ca CA.CRT] `' - )}` - ) - return exit(1) - } - - const crt = readX509File(argv.crt) - const key = readX509File(argv.key) - const ca = argv.ca ? readX509File(argv.ca) : '' - - const cert = await getCertIdCn(certs, args[0], currentTeam, user) - if (!cert) { - return exit(1) - } - const yes = await readConfirmation( - cert, - 'The following certificate will be replaced permanently\n' - ) - if (!yes) { - error('User abort') - return exit(0) - } - - await certs.put(cert.cn, crt, key, ca) - const elapsed = ms(new Date() - start) - console.log( - `${chalk.cyan('> Success!')} Certificate ${chalk.bold( - cert.cn - )} ${chalk.gray(`(${cert.uid})`)} replaced ${chalk.gray(`[${elapsed}]`)}` - ) - } else if (subcommand === 'rm' || subcommand === 'remove') { - if (args.length !== 1) { - error( - `Invalid number of arguments. Usage: ${chalk.cyan( - '`now certs rm `' - )}` - ) - return exit(1) - } - - const cert = await getCertIdCn(certs, args[0], currentTeam, user) - if (!cert) { - return exit(1) - } - const yes = await readConfirmation( - cert, - 'The following certificate will be removed permanently\n' - ) - if (!yes) { - error('User abort') - return exit(0) - } - - await certs.delete(cert.cn) - const elapsed = ms(new Date() - start) - console.log( - `${chalk.cyan('> Success!')} Certificate ${chalk.bold( - cert.cn - )} ${chalk.gray(`(${cert.uid})`)} removed ${chalk.gray(`[${elapsed}]`)}` - ) - } else { - error( - 'Please specify a valid subcommand: ls | create | renew | replace | rm' - ) - help() - exit(1) - } - return certs.close() -} - -process.on('uncaughtException', err => { - handleError(err) - exit(1) -}) - -function readConfirmation(cert, msg) { - return new Promise(resolve => { - const time = chalk.gray(ms(new Date() - new Date(cert.created)) + ' ago') - const tbl = table([[cert.uid, chalk.bold(cert.cn), time]], { - align: ['l', 'r', 'l'], - hsep: ' '.repeat(6) - }) - - process.stdout.write(`> ${msg}`) - process.stdout.write(' ' + tbl + '\n') - - process.stdout.write( - `${chalk.bold.red('> Are you sure?')} ${chalk.gray('[y/N] ')}` - ) - - process.stdin - .on('data', d => { - process.stdin.pause() - resolve(d.toString().trim().toLowerCase() === 'y') - }) - .resume() - }) -} - -function readX509File(file) { - return fs.readFileSync(path.resolve(file), 'utf8') -} - -async function getCertIdCn(certs, idOrCn, currentTeam, user) { - const list = await certs.ls() - const thecert = list.filter(cert => { - return cert.uid === idOrCn || cert.cn === idOrCn - })[0] - - if (!thecert) { - error( - `No certificate found by id or cn "${idOrCn}" under ${chalk.bold( - (currentTeam && currentTeam.slug) || user.username || user.email - )}` - ) - return null - } - - return thecert -} diff --git a/bin/now-deploy.js b/bin/now-deploy.js deleted file mode 100755 index 0d5ddf4..0000000 --- a/bin/now-deploy.js +++ /dev/null @@ -1,877 +0,0 @@ -#!/usr/bin/env node - -// Native -const { resolve, basename } = require('path') - -// Packages -const Progress = require('progress') -const fs = require('fs-extra') -const bytes = require('bytes') -const chalk = require('chalk') -const minimist = require('minimist') -const ms = require('ms') -const flatten = require('arr-flatten') -const dotenv = require('dotenv') -const { eraseLines } = require('ansi-escapes') -const { write: copy } = require('clipboardy') -const inquirer = require('inquirer') - -// Ours -const login = require('../lib/login') -const cfg = require('../lib/cfg') -const { version } = require('../lib/pkg') -const Logger = require('../lib/build-logger') -const Now = require('../lib') -const toHumanPath = require('../lib/utils/to-human-path') -const { handleError, error } = require('../lib/error') -const { fromGit, isRepoPath, gitPathParts } = require('../lib/git') -const readMetaData = require('../lib/read-metadata') -const checkPath = require('../lib/utils/check-path') -const { reAlias, assignAlias } = require('../lib/re-alias') -const exit = require('../lib/utils/exit') -const logo = require('../lib/utils/output/logo') -const cmd = require('../lib/utils/output/cmd') -const info = require('../lib/utils/output/info') -const wait = require('../lib/utils/output/wait') -const NowPlans = require('../lib/plans') -const promptBool = require('../lib/utils/input/prompt-bool') -const promptOptions = require('../lib/utils/input/prompt-options') -const note = require('../lib/utils/output/note') - -const argv = minimist(process.argv.slice(2), { - string: ['config', 'token', 'name', 'alias', 'session-affinity'], - boolean: [ - 'help', - 'version', - 'debug', - 'force', - 'links', - 'login', - 'no-clipboard', - 'forward-npm', - 'docker', - 'npm', - 'static' - ], - alias: { - env: 'e', - dotenv: 'E', - help: 'h', - config: 'c', - debug: 'd', - version: 'v', - force: 'f', - token: 't', - forceSync: 'F', - links: 'l', - login: 'L', - public: 'p', - 'no-clipboard': 'C', - 'forward-npm': 'N', - 'session-affinity': 'S', - name: 'n', - alias: 'a' - } -}) - -const help = () => { - console.log(` - ${chalk.bold(`${logo} now`)} [options] - - ${chalk.dim('Commands:')} - - ${chalk.dim('Cloud')} - - deploy [path] Performs a deployment ${chalk.bold( - '(default)' - )} - ls | list [app] List deployments - rm | remove [id] Remove a deployment - ln | alias [id] [url] Configures aliases for deployments - domains [name] Manages your domain names - certs [cmd] Manages your SSL certificates - secrets [name] Manages your secret environment variables - dns [name] Manages your DNS records - logs [url] Displays the logs for a deployment - scale [args] Scales the instance count of a deployment - help [cmd] Displays complete help for [cmd] - - ${chalk.dim('Administrative')} - - billing | cc [cmd] Manages your credit cards and billing methods - upgrade | downgrade [plan] Upgrades or downgrades your plan - teams [team] Manages your teams - switch Switches between teams and your account - login Login into your account or creates a new one - logout Logout from your account - - ${chalk.dim('Options:')} - - -h, --help Output usage information - -v, --version Output the version number - -n, --name Set the name of the deployment - -c ${chalk.underline('FILE')}, --config=${chalk.underline( - 'FILE' - )} Config file - -d, --debug Debug mode [off] - -f, --force Force a new deployment even if nothing has changed - -t ${chalk.underline('TOKEN')}, --token=${chalk.underline( - 'TOKEN' - )} Login token - -L, --login Configure login - -l, --links Copy symlinks without resolving their target - -p, --public Deployment is public (${chalk.dim( - '`/_src`' - )} is exposed) [on for oss, off for premium] - -e, --env Include an env var (e.g.: ${chalk.dim( - '`-e KEY=value`' - )}). Can appear many times. - -E ${chalk.underline('FILE')}, --dotenv=${chalk.underline( - 'FILE' - )} Include env vars from .env file. Defaults to '.env' - -C, --no-clipboard Do not attempt to copy URL to clipboard - -N, --forward-npm Forward login information to install private npm modules - --session-affinity Session affinity, \`ip\` (default) or \`random\` to control session affinity. - - ${chalk.dim( - 'Enforcable Types (when both package.json and Dockerfile exist):' - )} - - --npm Node.js application - --docker Docker container - --static Static file hosting - - ${chalk.dim('Examples:')} - - ${chalk.gray('–')} Deploys the current directory - - ${chalk.cyan('$ now')} - - ${chalk.gray('–')} Deploys a custom path ${chalk.dim('`/usr/src/project`')} - - ${chalk.cyan('$ now /usr/src/project')} - - ${chalk.gray('–')} Deploys a GitHub repository - - ${chalk.cyan('$ now user/repo#ref')} - - ${chalk.gray('–')} Deploys a GitHub, GitLab or Bitbucket repo using its URL - - ${chalk.cyan('$ now https://gitlab.com/user/repo')} - - ${chalk.gray('–')} Deploys with ENV vars - - ${chalk.cyan( - '$ now -e NODE_ENV=production -e MYSQL_PASSWORD=@mysql-password' - )} - - ${chalk.gray('–')} Displays comprehensive help for the subcommand ${chalk.dim( - '`list`' - )} - - ${chalk.cyan('$ now help list')} -`) -} - -let path = argv._[0] - -if (path) { - // If path is relative: resolve - // if path is absolute: clear up strange `/` etc - path = resolve(process.cwd(), path) -} else { - path = process.cwd() -} - -// If the current deployment is a repo -const gitRepo = {} - -// Options -const forceNew = argv.force -let deploymentName = argv.name -let sessionAffinity = argv['session-affinity'] -const debug = argv.debug -const clipboard = !argv['no-clipboard'] -const forwardNpm = argv['forward-npm'] -const forceSync = argv.forceSync -const shouldLogin = argv.login -const followSymlinks = !argv.links -const wantsPublic = argv.public -const apiUrl = argv.url || 'https://api.zeit.co' -const isTTY = process.stdout.isTTY -const quiet = !isTTY -const autoAliases = - typeof argv.alias === 'undefined' ? false : flatten([argv.alias]) - -if (argv.config) { - cfg.setConfigFile(argv.config) -} - -if (Array.isArray(autoAliases)) { - console.log( - `${chalk.red('Deprecated!')} The option ${chalk.grey( - '--alias' - )} will be removed soon.` - ) - console.log('Read more about the new way here: http://bit.ly/2l2v5Fg\n') -} - -const stopDeployment = msg => { - handleError(msg) - process.exit(1) -} - -const envFields = async list => { - const questions = [] - - for (const field of list) { - questions.push({ - name: field, - message: field - }) - } - - // eslint-disable-next-line import/no-unassigned-import - require('../lib/utils/input/patch-inquirer') - - info('Please enter the values for the following environment variables:') - const answers = await inquirer.prompt(questions) - - for (const answer in answers) { - if (!{}.hasOwnProperty.call(answers, answer)) { - continue - } - - const content = answers[answer] - - if (content === '') { - stopDeployment(`Enter a value for ${answer}`) - } - } - - return answers -} - -let alwaysForwardNpm - -async function main() { - if (argv.h || argv.help) { - help() - return exit(0) - } else if (argv.v || argv.version) { - console.log(version) - return exit(0) - } - - let config - - try { - config = await cfg.read({ token: argv.token }) - } catch (err) { - if (shouldLogin && err.userError) { - // We ignore user errors here, which means for example - // the token is mis-configured or revoked, if the user - // is attempting to log in again - config = {} - } else { - throw err - } - } - - let token = argv.token || config.token - if (!token || shouldLogin) { - try { - token = await login(apiUrl) - config = await cfg.read() - } catch (err) { - return stopDeployment(`Authentication error – ${err.message}`) - } - - console.log( - `> Logged in successfully. Token saved to ${chalk.bold('~/.now.json')}.` - ) - console.log( - `> Run ${cmd('now')} to deploy the current directory, or ${cmd( - 'now --help' - )} for usage info.\n` - ) - return exit(0) - } - - alwaysForwardNpm = config.forwardNpm - - // If we got to here then `token` should be set - try { - await sync({ token, config }) - } catch (err) { - return stopDeployment(err) - } -} - -async function sync({ token, config: { currentTeam, user } }) { - const start = Date.now() - const rawPath = argv._[0] - - const planPromise = new NowPlans({ - apiUrl, - token, - debug, - currentTeam - }).getCurrent() - - try { - await fs.stat(path) - } catch (err) { - let repo - let isValidRepo = false - - try { - isValidRepo = isRepoPath(rawPath) - } catch (err) { - if (err.code === 'INVALID_URL') { - stopDeployment(err) - } else { - throw err - } - } - - if (isValidRepo) { - const gitParts = gitPathParts(rawPath) - Object.assign(gitRepo, gitParts) - - const searchMessage = setTimeout(() => { - console.log(`> Didn't find directory. Searching on ${gitRepo.type}...`) - }, 500) - - try { - repo = await fromGit(rawPath, debug) - } catch (err) {} - - clearTimeout(searchMessage) - } - - if (repo) { - // Tell now which directory to deploy - path = repo.path - - // Set global variable for deleting tmp dir later - // once the deployment has finished - Object.assign(gitRepo, repo) - } else if (isValidRepo) { - const gitRef = gitRepo.ref ? `with "${chalk.bold(gitRepo.ref)}" ` : '' - stopDeployment( - `There's no repository named "${chalk.bold( - gitRepo.main - )}" ${gitRef}on ${gitRepo.type}` - ) - } else { - error(`The specified directory "${basename(path)}" doesn't exist.`) - process.exit(1) - } - } - - // Make sure that directory is deployable - try { - await checkPath(path) - } catch (err) { - error(err) - return - } - - if (!quiet) { - if (gitRepo.main) { - const gitRef = gitRepo.ref ? ` at "${chalk.bold(gitRepo.ref)}" ` : '' - console.log( - `> Deploying ${gitRepo.type} repository "${chalk.bold( - gitRepo.main - )}" ${gitRef} under ${chalk.bold( - (currentTeam && currentTeam.slug) || user.username || user.email - )}` - ) - } else { - console.log( - `> Deploying ${chalk.bold(toHumanPath(path))} under ${chalk.bold( - (currentTeam && currentTeam.slug) || user.username || user.email - )}` - ) - } - } - - let deploymentType - - // CLI deployment type explicit overrides - if (argv.docker) { - if (debug) { - console.log(`> [debug] Forcing \`deploymentType\` = \`docker\``) - } - - deploymentType = 'docker' - } else if (argv.npm) { - if (debug) { - console.log(`> [debug] Forcing \`deploymentType\` = \`npm\``) - } - - deploymentType = 'npm' - } else if (argv.static) { - if (debug) { - console.log(`> [debug] Forcing \`deploymentType\` = \`static\``) - } - - deploymentType = 'static' - } - - let meta - ;({ meta, deploymentName, deploymentType, sessionAffinity } = await readMeta( - path, - deploymentName, - deploymentType, - sessionAffinity - )) - const nowConfig = meta.nowConfig - - const now = new Now({ apiUrl, token, debug, currentTeam }) - - let dotenvConfig - let dotenvOption - - if (argv.dotenv) { - dotenvOption = argv.dotenv - } else if (nowConfig && nowConfig.dotenv) { - dotenvOption = nowConfig.dotenv - } - - if (dotenvOption) { - const dotenvFileName = - typeof dotenvOption === 'string' ? dotenvOption : '.env' - - if (!fs.existsSync(dotenvFileName)) { - error(`--dotenv flag is set but ${dotenvFileName} file is missing`) - return process.exit(1) - } - - const dotenvFile = await fs.readFile(dotenvFileName) - dotenvConfig = dotenv.parse(dotenvFile) - } - - let pkgEnv = nowConfig && nowConfig.env - const argEnv = [].concat(argv.env || []) - - if (pkgEnv && Array.isArray(nowConfig.env)) { - const defined = argEnv.join() - const askFor = nowConfig.env.filter(item => !defined.includes(`${item}=`)) - - pkgEnv = await envFields(askFor) - } - - // Merge `now.env` from package.json with `-e` arguments - const envs = [ - ...Object.keys(dotenvConfig || {}).map(k => `${k}=${dotenvConfig[k]}`), - ...Object.keys(pkgEnv || {}).map(k => `${k}=${pkgEnv[k]}`), - ...argEnv - ] - - let secrets - const findSecret = async uidOrName => { - if (!secrets) { - secrets = await now.listSecrets() - } - - return secrets.filter(secret => { - return secret.name === uidOrName || secret.uid === uidOrName - }) - } - - const env_ = await Promise.all( - envs.map(async kv => { - if (typeof kv !== 'string') { - error('Env key and value missing') - return process.exit(1) - } - - const [key, ...rest] = kv.split('=') - let val - - if (rest.length > 0) { - val = rest.join('=') - } - - if (/[^A-z0-9_]/i.test(key)) { - error( - `Invalid ${chalk.dim('-e')} key ${chalk.bold( - `"${chalk.bold(key)}"` - )}. Only letters, digits and underscores are allowed.` - ) - return process.exit(1) - } - - if (!key) { - error(`Invalid env option ${chalk.bold(`"${kv}"`)}`) - return process.exit(1) - } - - if (val === undefined) { - if (key in process.env) { - console.log( - `> Reading ${chalk.bold( - `"${chalk.bold(key)}"` - )} from your env (as no value was specified)` - ) - // Escape value if it begins with @ - val = process.env[key].replace(/^@/, '\\@') - } else { - error( - `No value specified for env ${chalk.bold( - `"${chalk.bold(key)}"` - )} and it was not found in your env.` - ) - return process.exit(1) - } - } - - if (val[0] === '@') { - const uidOrName = val.substr(1) - const secrets = await findSecret(uidOrName) - if (secrets.length === 0) { - if (uidOrName === '') { - error( - `Empty reference provided for env key ${chalk.bold( - `"${chalk.bold(key)}"` - )}` - ) - } else { - error( - `No secret found by uid or name ${chalk.bold(`"${uidOrName}"`)}` - ) - } - return process.exit(1) - } else if (secrets.length > 1) { - error( - `Ambiguous secret ${chalk.bold( - `"${uidOrName}"` - )} (matches ${chalk.bold(secrets.length)} secrets)` - ) - return process.exit(1) - } - - val = { uid: secrets[0].uid } - } - - return [key, typeof val === 'string' ? val.replace(/^\\@/, '@') : val] - }) - ) - - const env = {} - env_.filter(v => Boolean(v)).forEach(([key, val]) => { - if (key in env) { - note(`Overriding duplicate env key ${chalk.bold(`"${key}"`)}`) - } - - env[key] = val - }) - - try { - await now.create( - path, - Object.assign( - { - env, - followSymlinks, - forceNew, - forceSync, - forwardNpm: alwaysForwardNpm || forwardNpm, - quiet, - wantsPublic, - sessionAffinity - }, - meta - ) - ) - } catch (err) { - if (debug) { - console.log(`> [debug] error: ${err}\n${err.stack}`) - } - - return stopDeployment(err) - } - - const { url } = now - const elapsed = ms(new Date() - start) - - if (isTTY) { - if (clipboard) { - try { - await copy(url) - console.log( - `${chalk.cyan('> Ready!')} ${chalk.bold( - url - )} (copied to clipboard) [${elapsed}]` - ) - } catch (err) { - console.log(`${chalk.cyan('> Ready!')} ${chalk.bold(url)} [${elapsed}]`) - } - } else { - console.log(`> ${url} [${elapsed}]`) - } - } else { - process.stdout.write(url) - } - - const startU = new Date() - - const complete = ({ syncCount }) => { - if (!quiet) { - const elapsedU = ms(new Date() - startU) - console.log( - `> Synced ${syncCount} (${bytes(now.syncAmount)}) [${elapsedU}] ` - ) - console.log('> Initializing…') - } - - // Close http2 agent - now.close() - - // Show build logs - if (!quiet) { - if (deploymentType === 'static') { - console.log(`${chalk.cyan('> Deployment complete!')}`) - } else { - printLogs(now.host, token, currentTeam, user) - } - } - } - - const plan = await planPromise - - if (plan.id === 'oss' && !wantsPublic) { - if (isTTY) { - info( - `${chalk.bold( - (currentTeam && `${currentTeam.slug} is`) || - `You (${user.username || user.email}) are` - )} on the OSS plan. Your code and logs will be made ${chalk.bold( - 'public' - )}.` - ) - - const proceed = await promptBool( - 'Are you sure you want to proceed with the deployment?', - { trailing: eraseLines(1) } - ) - - if (proceed) { - note(`You can use ${cmd('now --public')} to skip this prompt`) - } else { - const stopSpinner = wait('Canceling deployment') - await now.remove(now.id, { hard: true }) - stopSpinner() - info('Deployment aborted. No files were synced.') - info(`You can upgrade by running ${cmd('now upgrade')}.`) - return exit() - } - } else if (!wantsPublic) { - const msg = - '\nYou are on the OSS plan. Your code and logs will be made public.' + - ' If you agree with that, please run again with --public.' - return stopDeployment(msg) - } - } - - if (now.syncAmount) { - if (debug && now.syncFileCount !== now.fileCount) { - console.log( - `> [debug] total files ${now.fileCount}, ${now.syncFileCount} changed. ` - ) - } - const size = bytes(now.syncAmount) - const syncCount = `${now.syncFileCount} file${now.syncFileCount > 1 - ? 's' - : ''}` - const bar = new Progress( - `> Upload [:bar] :percent :etas (${size}) [${syncCount}]`, - { - width: 20, - complete: '=', - incomplete: '', - total: now.syncAmount, - clear: true - } - ) - - now.upload() - - now.on('upload', ({ names, data }) => { - const amount = data.length - if (debug) { - console.log( - `> [debug] Uploaded: ${names.join(' ')} (${bytes(data.length)})` - ) - } - bar.tick(amount) - }) - - now.on('complete', () => complete({ syncCount })) - - now.on('error', err => { - error('Upload failed') - return stopDeployment(err) - }) - } else { - if (!quiet) { - console.log(`> Initializing…`) - } - - // Close http2 agent - now.close() - - // Show build logs - if (deploymentType === 'static' && !quiet) { - console.log(`${chalk.cyan('> Deployment complete!')}`) - } else { - printLogs(now.host, token, currentTeam, user) - } - } -} - -async function readMeta(path, deploymentName, deploymentType, sessionAffinity) { - try { - const meta = await readMetaData(path, { - deploymentType, - deploymentName, - quiet: true, - sessionAffinity - }) - - if (!deploymentType) { - deploymentType = meta.type - - if (debug) { - console.log( - `> [debug] Detected \`deploymentType\` = \`${deploymentType}\`` - ) - } - } - - if (!deploymentName) { - deploymentName = meta.name - - if (debug) { - console.log( - `> [debug] Detected \`deploymentName\` = "${deploymentName}"` - ) - } - } - - return { - meta, - deploymentName, - deploymentType, - sessionAffinity - } - } catch (err) { - if (isTTY && err.code === 'MULTIPLE_MANIFESTS') { - if (debug) { - console.log('> [debug] Multiple manifests found, disambiguating') - } - - console.log( - `> Two manifests found. Press [${chalk.bold( - 'n' - )}] to deploy or re-run with --flag` - ) - - deploymentType = await promptOptions([ - ['npm', `${chalk.bold('package.json')}\t${chalk.gray(' --npm')} `], - ['docker', `${chalk.bold('Dockerfile')}\t${chalk.gray('--docker')} `] - ]) - - if (debug) { - console.log( - `> [debug] Selected \`deploymentType\` = "${deploymentType}"` - ) - } - - return readMeta(path, deploymentName, deploymentType) - } - throw err - } -} - -function printLogs(host, token, currentTeam, user) { - // Log build - const logger = new Logger(host, token, { debug, quiet }) - - logger.on('error', async err => { - if (!quiet) { - if (err && err.type === 'BUILD_ERROR') { - error( - `The build step of your project failed. To retry, run ${cmd( - 'now --force' - )}.` - ) - } else { - error('Deployment failed') - } - } - - if (gitRepo && gitRepo.cleanup) { - // Delete temporary directory that contains repository - gitRepo.cleanup() - - if (debug) { - console.log(`> [debug] Removed temporary repo directory`) - } - } - - process.exit(1) - }) - - logger.on('close', async () => { - if (Array.isArray(autoAliases)) { - const aliasList = autoAliases.filter(item => item !== '') - - if (aliasList.length > 0) { - const assignments = [] - - for (const alias of aliasList) { - assignments.push( - assignAlias(alias, token, host, apiUrl, debug, currentTeam, user) - ) - } - - await Promise.all(assignments) - } else { - await reAlias( - token, - host, - null, - help, - exit, - apiUrl, - debug, - currentTeam, - user - ) - } - } - - if (!quiet) { - console.log(`${chalk.cyan('> Deployment complete!')}`) - } - - if (gitRepo && gitRepo.cleanup) { - // Delete temporary directory that contains repository - gitRepo.cleanup() - - if (debug) { - console.log(`> [debug] Removed temporary repo directory`) - } - } - - process.exit(0) - }) -} - -main().catch(err => { - handleError(err, { debug }) - process.exit(1) -}) diff --git a/bin/now-dns.js b/bin/now-dns.js deleted file mode 100755 index 1fd542b..0000000 --- a/bin/now-dns.js +++ /dev/null @@ -1,343 +0,0 @@ -#!/usr/bin/env node - -// Packages -const chalk = require('chalk') -const minimist = require('minimist') -const ms = require('ms') -const table = require('text-table') - -// Ours -const cfg = require('../lib/cfg') -const DomainRecords = require('../lib/domain-records') -const indent = require('../lib/indent') -const login = require('../lib/login') -const strlen = require('../lib/strlen') -const { handleError, error } = require('../lib/error') -const exit = require('../lib/utils/exit') -const logo = require('../lib/utils/output/logo') - -const argv = minimist(process.argv.slice(2), { - string: ['config'], - boolean: ['help', 'debug'], - alias: { - help: 'h', - config: 'c', - debug: 'd', - token: 't' - } -}) - -const subcommand = argv._[0] - -// Options -const help = () => { - console.log(` - ${chalk.bold(`${logo} now dns ls`)} [domain] - ${chalk.bold( - `${logo} now dns add` - )} - ${chalk.bold(`${logo} now dns add`)} MX - ${chalk.bold( - `${logo} now dns add` - )} SRV - ${chalk.bold(`${logo} now dns rm`)} - - ${chalk.dim('Options:')} - - -h, --help output usage information - -c ${chalk.bold.underline('FILE')}, --config=${chalk.bold.underline( - 'FILE' - )} config file - -d, --debug debug mode [off] - -t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline( - 'TOKEN' - )} login token - - ${chalk.dim('Examples:')} - - ${chalk.gray('–')} List all your DNS records - - ${chalk.cyan('$ now dns ls')} - - ${chalk.gray('–')} Add an A record for a subdomain - - ${chalk.cyan( - '$ now dns add A ' - )} - ${chalk.cyan('$ now dns add zeit.rocks api A 198.51.100.100')} - - ${chalk.gray('–')} Add an MX record (@ as a name refers to the domain) - - ${chalk.cyan( - '$ now dns add @ MX ' - )} - ${chalk.cyan('$ now dns add zeit.rocks @ MX mail.zeit.rocks 10')} -`) -} - -// Options -const debug = argv.debug -const apiUrl = argv.url || 'https://api.zeit.co' -if (argv.config) { - cfg.setConfigFile(argv.config) -} - -if (argv.help || !subcommand) { - help() - exit(0) -} else { - Promise.resolve() - .then(async () => { - const config = await cfg.read({ token: argv.token }) - - let token - try { - token = config.token || (await login(apiUrl)) - } catch (err) { - error(`Authentication error – ${err.message}`) - exit(1) - } - - try { - await run({ token, config }) - } catch (err) { - handleError(err) - exit(1) - } - }) - .catch(err => { - handleError(err) - process.exit(1) - }) -} - -async function run({ token, config: { currentTeam, user } }) { - const domainRecords = new DomainRecords({ apiUrl, token, debug, currentTeam }) - const args = argv._.slice(1) - const start = Date.now() - - if (subcommand === 'ls' || subcommand === 'list') { - if (args.length > 1) { - error( - `Invalid number of arguments. Usage: ${chalk.cyan( - '`now dns ls [domain]`' - )}` - ) - return exit(1) - } - - const elapsed = ms(new Date() - start) - const res = await domainRecords.ls(args[0]) - const text = [] - let count = 0 - res.forEach((records, domain) => { - count += records.length - if (records.length > 0) { - const cur = Date.now() - const header = [ - ['', 'id', 'name', 'type', 'value', 'aux', 'created'].map(s => - chalk.dim(s) - ) - ] - const out = table( - header.concat( - records.map(record => { - const time = chalk.gray( - ms(cur - new Date(Number(record.created))) + ' ago' - ) - const aux = (() => { - if (record.mxPriority !== undefined) return record.mxPriority - if (record.priority !== undefined) return record.priority - return '' - })() - return [ - '', - record.id, - record.name, - record.type, - record.value, - aux, - time - ] - }) - ), - { - align: ['l', 'r', 'l', 'l', 'l', 'l'], - hsep: ' '.repeat(2), - stringLength: strlen - } - ) - text.push(`\n\n${chalk.bold(domain)}\n${indent(out, 2)}`) - } - }) - console.log( - `> ${count} record${count === 1 ? '' : 's'} found ${chalk.gray( - `[${elapsed}]` - )} under ${chalk.bold( - (currentTeam && currentTeam.slug) || user.username || user.email - )}` - ) - console.log(text.join('')) - } else if (subcommand === 'add') { - const param = parseAddArgs(args) - if (!param) { - error( - `Invalid number of arguments. See: ${chalk.cyan( - '`now dns --help`' - )} for usage.` - ) - return exit(1) - } - const record = await domainRecords.create(param.domain, param.data) - const elapsed = ms(new Date() - start) - console.log( - `${chalk.cyan('> Success!')} A new DNS record for domain ${chalk.bold( - param.domain - )} ${chalk.gray(`(${record.uid})`)} created ${chalk.gray( - `[${elapsed}]` - )} (${chalk.bold( - (currentTeam && currentTeam.slug) || user.username || user.email - )})` - ) - } else if (subcommand === 'rm' || subcommand === 'remove') { - if (args.length !== 1) { - error( - `Invalid number of arguments. Usage: ${chalk.cyan('`now dns rm `')}` - ) - return exit(1) - } - - const record = await domainRecords.getRecord(args[0]) - if (!record) { - error('DNS record not found') - return exit(1) - } - - const yes = await readConfirmation( - record, - 'The following record will be removed permanently \n' - ) - if (!yes) { - error('User abort') - return exit(0) - } - - await domainRecords.delete(record.domain, record.id) - const elapsed = ms(new Date() - start) - console.log( - `${chalk.cyan('> Success!')} Record ${chalk.gray( - `${record.id}` - )} removed ${chalk.gray(`[${elapsed}]`)}` - ) - } else { - error('Please specify a valid subcommand: ls | add | rm') - help() - exit(1) - } - return domainRecords.close() -} - -process.on('uncaughtException', err => { - handleError(err) - exit(1) -}) - -function parseAddArgs(args) { - if (!args || args.length < 4) { - return null - } - - const domain = args[0] - const name = args[1] === '@' ? '' : args[1].toString() - const type = args[2] - const value = args[3] - - if (!(domain && typeof name === 'string' && type)) { - return null - } - - if (type === 'MX') { - if (args.length !== 5) { - return null - } - - return { - domain, - data: { - name, - type, - value, - mxPriority: args[4] - } - } - } else if (type === 'SRV') { - if (args.length !== 7) { - return null - } - - return { - domain, - data: { - name, - type, - srv: { - priority: value, - weight: args[4], - port: args[5], - target: args[6] - } - } - } - } - - if (args.length !== 4) { - return null - } - - return { - domain, - data: { - name, - type, - value - } - } -} - -function readConfirmation(record, msg) { - return new Promise(resolve => { - const time = chalk.gray( - ms(new Date() - new Date(Number(record.created))) + ' ago' - ) - const tbl = table( - [ - [ - record.id, - chalk.bold( - `${record.name.length > 0 - ? record.name + '.' - : ''}${record.domain} ${record.type} ${record.value} ${record.mxPriority - ? record.mxPriority - : ''}` - ), - time - ] - ], - { align: ['l', 'r', 'l'], hsep: ' '.repeat(6) } - ) - - process.stdout.write(`> ${msg}`) - process.stdout.write(' ' + tbl + '\n') - - process.stdout.write( - `${chalk.bold.red('> Are you sure?')} ${chalk.gray('[y/N] ')}` - ) - - process.stdin - .on('data', d => { - process.stdin.pause() - resolve(d.toString().trim().toLowerCase() === 'y') - }) - .resume() - }) -} diff --git a/bin/now-domains.js b/bin/now-domains.js deleted file mode 100755 index 9022b73..0000000 --- a/bin/now-domains.js +++ /dev/null @@ -1,423 +0,0 @@ -#!/usr/bin/env node - -// Native -const { resolve } = require('path') - -// Packages -const chalk = require('chalk') -const minimist = require('minimist') -const ms = require('ms') -const psl = require('psl') -const table = require('text-table') - -// Ours -const NowDomains = require('../lib/domains') -const cfg = require('../lib/cfg') -const exit = require('../lib/utils/exit') -const login = require('../lib/login') -const logo = require('../lib/utils/output/logo') -const promptBool = require('../lib/utils/input/prompt-bool') -const strlen = require('../lib/strlen') -const toHost = require('../lib/to-host') -const { handleError, error } = require('../lib/error') - -const argv = minimist(process.argv.slice(2), { - string: ['coupon', 'token'], - boolean: ['help', 'debug', 'external', 'force'], - alias: { - help: 'h', - coupon: 'c', - debug: 'd', - external: 'e', - force: 'f', - token: 't' - } -}) - -const subcommand = argv._[0] - -// Options -const help = () => { - console.log(` - ${chalk.bold(`${logo} now domains`)} - - ${chalk.dim('Options:')} - - -h, --help Output usage information - -d, --debug Debug mode [off] - -e, --external Use external DNS server - -f, --force Skip DNS verification - -t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline( - 'TOKEN' - )} Login token - - ${chalk.dim('Examples:')} - - ${chalk.gray('–')} Lists all your domains: - - ${chalk.cyan('$ now domains ls')} - - ${chalk.gray('–')} Buy a new domain: - - ${chalk.cyan(`$ now domains buy ${chalk.underline('domain-name.com')}`)} - - ${chalk.gray('–')} Adds a domain name: - - ${chalk.cyan(`$ now domains add ${chalk.underline('domain-name.com')}`)} - - Make sure the domain's DNS nameservers are at least 2 of these: - - ${chalk.gray('–')} ${chalk.underline( - 'california.zeit.world' - )} ${chalk.dim('173.255.215.107')} - ${chalk.gray('–')} ${chalk.underline( - 'london.zeit.world' - )} ${chalk.dim('178.62.47.76')} - ${chalk.gray('–')} ${chalk.underline( - 'newark.zeit.world' - )} ${chalk.dim('173.255.231.87')} - ${chalk.gray('–')} ${chalk.underline( - 'amsterdam.zeit.world' - )} ${chalk.dim('188.226.197.55')} - ${chalk.gray('–')} ${chalk.underline( - 'dallas.zeit.world' - )} ${chalk.dim('173.192.101.194')} - ${chalk.gray('–')} ${chalk.underline( - 'paris.zeit.world' - )} ${chalk.dim('37.123.115.172')} - ${chalk.gray('–')} ${chalk.underline( - 'singapore.zeit.world' - )} ${chalk.dim('119.81.97.170')} - ${chalk.gray('–')} ${chalk.underline( - 'sydney.zeit.world' - )} ${chalk.dim('52.64.171.200')} - ${chalk.gray('–')} ${chalk.underline( - 'frankfurt.zeit.world' - )} ${chalk.dim('91.109.245.139')} - ${chalk.gray('–')} ${chalk.underline( - 'iowa.zeit.world' - )} ${chalk.dim('23.236.59.22')} - - ${chalk.yellow('NOTE:')} running ${chalk.dim( - '`now alias`' - )} will automatically register your domain - if it's configured with these nameservers (no need to ${chalk.dim( - '`domain add`' - )}). - - For more details head to ${chalk.underline('https://zeit.world')}. - - ${chalk.gray('–')} Removing a domain: - - ${chalk.cyan('$ now domain rm my-app.com')} - - or - - ${chalk.cyan('$ now domain rm domainId')} - - To get the list of domain ids, use ${chalk.dim('`now domains ls`')}. - - ${chalk.gray( - '–' - )} Adding and verifying a domain name using zeit.world nameservers: - - ${chalk.cyan('$ now domain add my-app.com')} - - The command will tell you if the domain was verified succesfully. In case the domain was not verified succesfully you should retry adding the domain after some time. - - ${chalk.gray( - '–' - )} Adding and verifying a domain name using an external nameserver: - - ${chalk.cyan('$ now domain add -e my-app.com')} - - and follow the verification instructions if requested. Finally, rerun the same command after completing the verification step. -`) -} - -// Options -const debug = argv.debug -const apiUrl = argv.url || 'https://api.zeit.co' - -if (argv.help || !subcommand) { - help() - exit(0) -} else { - Promise.resolve() - .then(async () => { - const config = await cfg.read({ token: argv.token }) - - let token - try { - token = config.token || (await login(apiUrl)) - } catch (err) { - error(`Authentication error – ${err.message}`) - exit(1) - } - try { - await run({ token, config }) - } catch (err) { - if (err.userError) { - error(err.message) - } else { - error(`Unknown error: ${err}\n${err.stack}`) - } - exit(1) - } - }) - .catch(err => { - handleError(err) - process.exit(1) - }) -} - -async function run({ token, config: { currentTeam, user } }) { - const domain = new NowDomains({ apiUrl, token, debug, currentTeam }) - const args = argv._.slice(1) - - switch (subcommand) { - case 'ls': - case 'list': { - if (args.length !== 0) { - error('Invalid number of arguments') - return exit(1) - } - - const start_ = new Date() - const domains = await domain.ls() - domains.sort((a, b) => new Date(b.created) - new Date(a.created)) - const current = new Date() - const header = [ - ['', 'domain', 'dns', 'verified', 'created'].map(s => chalk.dim(s)) - ] - const out = - domains.length === 0 - ? null - : table( - header.concat( - domains.map(domain => { - const ns = domain.isExternal ? 'external' : 'zeit.world' - const url = chalk.bold(domain.name) - const time = chalk.gray( - ms(current - new Date(domain.created)) + ' ago' - ) - return ['', url, ns, domain.verified, time] - }) - ), - { - align: ['l', 'l', 'l', 'l', 'l'], - hsep: ' '.repeat(2), - stringLength: strlen - } - ) - - const elapsed_ = ms(new Date() - start_) - console.log( - `> ${domains.length} domain${domains.length === 1 - ? '' - : 's'} found under ${chalk.bold( - (currentTeam && currentTeam.slug) || user.username || user.email - )} ${chalk.gray(`[${elapsed_}]`)}` - ) - - if (out) { - console.log('\n' + out + '\n') - } - - break - } - case 'rm': - case 'remove': { - if (args.length !== 1) { - error('Invalid number of arguments') - return exit(1) - } - - const _target = String(args[0]) - if (!_target) { - const err = new Error('No domain specified') - err.userError = true - throw err - } - - const _domains = await domain.ls() - const _domain = findDomain(_target, _domains) - - if (!_domain) { - const err = new Error( - `Domain not found by "${_target}". Run ${chalk.dim( - '`now domains ls`' - )} to see your domains.` - ) - err.userError = true - throw err - } - - try { - const confirmation = (await readConfirmation( - domain, - _domain - )).toLowerCase() - if (confirmation !== 'y' && confirmation !== 'yes') { - console.log('\n> Aborted') - process.exit(0) - } - - const start = new Date() - await domain.rm(_domain) - const elapsed = ms(new Date() - start) - console.log( - `${chalk.cyan('> Success!')} Domain ${chalk.bold( - _domain.uid - )} removed [${elapsed}]` - ) - } catch (err) { - error(err) - exit(1) - } - break - } - case 'add': - case 'set': { - if (args.length !== 1) { - error('Invalid number of arguments') - return exit(1) - } - const name = String(args[0]) - - const parsedDomain = psl.parse(name) - if (parsedDomain.subdomain) { - const msg = - `You are adding "${name}" as a domain name which seems to contain a subdomain part "${parsedDomain.subdomain}".\n` + - ' This is probably wrong unless you really know what you are doing.\n' + - ` To add the root domain instead please run: ${chalk.cyan( - 'now domain add ' + - (argv.external ? '-e ' : '') + - parsedDomain.domain - )}\n` + - ` Continue adding "${name}" as a domain name?` - if (!await promptBool(msg)) { - return exit(1) - } - } - - const start = new Date() - const { uid, code, created, verified } = await domain.add( - name, - argv.force, - argv.external - ) - const elapsed = ms(new Date() - start) - if (created) { - console.log( - `${chalk.cyan('> Success!')} Domain ${chalk.bold( - chalk.underline(name) - )} ${chalk.dim(`(${uid})`)} added [${elapsed}]` - ) - } else if (verified) { - console.log( - `${chalk.cyan('> Success!')} Domain ${chalk.bold( - chalk.underline(name) - )} ${chalk.dim(`(${uid})`)} verified [${elapsed}]` - ) - } else if (code === 'not_modified') { - console.log( - `${chalk.cyan('> Success!')} Domain ${chalk.bold( - chalk.underline(name) - )} ${chalk.dim(`(${uid})`)} already exists [${elapsed}]` - ) - } else { - console.log( - '> Verification required: Please rerun this command after some time' - ) - } - break - } - case 'buy': { - await require(resolve(__dirname, 'domains', 'buy.js'))({ - domains: domain, - args, - currentTeam, - user, - coupon: argv.coupon - }) - break - } - default: - error('Please specify a valid subcommand: ls | add | rm') - help() - exit(1) - } - - domain.close() -} - -async function readConfirmation(domain, _domain) { - return new Promise(resolve => { - const time = chalk.gray(ms(new Date() - new Date(_domain.created)) + ' ago') - const tbl = table([[chalk.underline(`https://${_domain.name}`), time]], { - align: ['r', 'l'], - hsep: ' '.repeat(6) - }) - - process.stdout.write('> The following domain will be removed permanently\n') - process.stdout.write(' ' + tbl + '\n') - - if (_domain.aliases.length > 0) { - process.stdout.write( - `> ${chalk.yellow('Warning!')} This domain's ` + - `${chalk.bold( - _domain.aliases.length + - ' alias' + - (_domain.aliases.length === 1 ? '' : 'es') - )} ` + - `will be removed. Run ${chalk.dim('`now alias ls`')} to list them.\n` - ) - } - if (_domain.certs.length > 0) { - process.stdout.write( - `> ${chalk.yellow('Warning!')} This domain's ` + - `${chalk.bold( - _domain.certs.length + - ' certificate' + - (_domain.certs.length === 1 ? '' : 's') - )} ` + - `will be removed. Run ${chalk.dim('`now cert ls`')} to list them.\n` - ) - } - - process.stdout.write( - `${chalk.bold.red('> Are you sure?')} ${chalk.gray('[y/N] ')}` - ) - - process.stdin - .on('data', d => { - process.stdin.pause() - resolve(d.toString().trim()) - }) - .resume() - }) -} - -function findDomain(val, list) { - return list.find(d => { - if (d.uid === val) { - if (debug) { - console.log(`> [debug] matched domain ${d.uid} by uid`) - } - - return true - } - - // Match prefix - if (d.name === toHost(val)) { - if (debug) { - console.log(`> [debug] matched domain ${d.uid} by name ${d.name}`) - } - - return true - } - - return false - }) -} diff --git a/bin/now-list.js b/bin/now-list.js deleted file mode 100755 index 48f969a..0000000 --- a/bin/now-list.js +++ /dev/null @@ -1,247 +0,0 @@ -#!/usr/bin/env node - -// Packages -const minimist = require('minimist') -const chalk = require('chalk') -const ms = require('ms') -const printf = require('printf') -require('epipebomb')() -const supportsColor = require('supports-color') - -// Ours -const Now = require('../lib') -const login = require('../lib/login') -const cfg = require('../lib/cfg') -const { handleError, error } = require('../lib/error') -const logo = require('../lib/utils/output/logo') -const sort = require('../lib/sort-deployments') - -const argv = minimist(process.argv.slice(2), { - string: ['config', 'token'], - boolean: ['help', 'debug', 'all'], - alias: { - help: 'h', - config: 'c', - debug: 'd', - token: 't' - } -}) - -const help = () => { - console.log(` - ${chalk.bold(`${logo} now list`)} [app] - - ${chalk.dim('Options:')} - - -h, --help Output usage information - -c ${chalk.bold.underline('FILE')}, --config=${chalk.bold.underline( - 'FILE' - )} Config file - -d, --debug Debug mode [off] - -t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline( - 'TOKEN' - )} Login token - - ${chalk.dim('Examples:')} - - ${chalk.gray('–')} List all deployments - - ${chalk.cyan('$ now ls')} - - ${chalk.gray('–')} List all deployments for the app ${chalk.dim('`my-app`')} - - ${chalk.cyan('$ now ls my-app')} - - ${chalk.dim('Alias:')} ls -`) -} - -if (argv.help) { - help() - process.exit(0) -} - -const app = argv._[0] - -// Options -const debug = argv.debug -const apiUrl = argv.url || 'https://api.zeit.co' - -if (argv.config) { - cfg.setConfigFile(argv.config) -} - -Promise.resolve() - .then(async () => { - const config = await cfg.read({ token: argv.token }) - - let token - try { - token = config.token || (await login(apiUrl)) - } catch (err) { - error(`Authentication error – ${err.message}`) - process.exit(1) - } - - if (!config.token) { - console.log( - `> Logged in successfully. Token saved to ${chalk.bold('~/.now.json')}.` - ) - process.exit(0) - } - - try { - await list({ token, config }) - } catch (err) { - error(`Unknown error: ${err}\n${err.stack}`) - process.exit(1) - } - }) - .catch(err => { - handleError(err) - process.exit(1) - }) - -async function list({ token, config: { currentTeam, user } }) { - const now = new Now({ apiUrl, token, debug, currentTeam }) - const start = new Date() - - if (argv.all && !app) { - console.log('> You must define an app when using `--all`') - process.exit(1) - } - let deployments - try { - deployments = await now.list(app) - } catch (err) { - handleError(err) - process.exit(1) - } - - if (!deployments || (Array.isArray(deployments) && deployments.length <= 0)) { - const match = await now.findDeployment(app) - if (match !== null && typeof match !== 'undefined') { - deployments = Array.of(match) - } - } - if (!deployments || (Array.isArray(deployments) && deployments.length <= 0)) { - const aliases = await now.listAliases() - - const item = aliases.find(e => e.uid === app || e.alias === app) - if (item) { - const match = await now.findDeployment(item.deploymentId) - if (match !== null && typeof match !== 'undefined') { - deployments = Array.of(match) - } - } - } - - now.close() - - const apps = new Map() - - if (argv.all) { - await Promise.all( - deployments.map(async ({ uid }, i) => { - deployments[i].instances = await now.listInstances(uid) - }) - ) - } - - for (const dep of deployments) { - const deps = apps.get(dep.name) || [] - apps.set(dep.name, deps.concat(dep)) - } - - const sorted = await sort([...apps]) - - const urlLength = - deployments.reduce((acc, i) => { - return Math.max(acc, (i.url && i.url.length) || 0) - }, 0) + 5 - const timeNow = new Date() - console.log( - `> ${deployments.length} deployment${deployments.length === 1 - ? '' - : 's'} found under ${chalk.bold( - (currentTeam && currentTeam.slug) || user.username || user.email - )} ${chalk.grey('[' + ms(timeNow - start) + ']')}` - ) - - let shouldShowAllInfo = false - for (const app of apps) { - shouldShowAllInfo = - app[1].length > 5 || - app.find(depl => { - return depl.scale && depl.scale.current > 1 - }) - if (shouldShowAllInfo) { - break - } - } - if (!argv.all && shouldShowAllInfo) { - console.log( - `> To expand the list and see instances run ${chalk.cyan( - '`now ls --all [app]`' - )}` - ) - } - console.log() - sorted.forEach(([name, deps]) => { - const listedDeployments = argv.all ? deps : deps.slice(0, 5) - console.log( - `${chalk.bold(name)} ${chalk.gray( - '(' + listedDeployments.length + ' of ' + deps.length + ' total)' - )}` - ) - const urlSpec = `%-${urlLength}s` - console.log( - printf( - ` ${chalk.grey(urlSpec + ' %8s %-16s %8s')}`, - 'url', - 'inst #', - 'state', - 'age' - ) - ) - listedDeployments.forEach(dep => { - let state = dep.state - let extraSpaceForState = 0 - if (state === null || typeof state === 'undefined') { - state = 'DEPLOYMENT_ERROR' - } - if (/ERROR/.test(state)) { - state = chalk.red(state) - extraSpaceForState = 10 - } else if (state === 'FROZEN') { - state = chalk.grey(state) - extraSpaceForState = 10 - } - let spec - if (supportsColor) { - spec = ` %-${urlLength + 10}s %8s %-${extraSpaceForState + 16}s %8s` - } else { - spec = ` %-${urlLength + 1}s %8s %-${16}s %8s` - } - - console.log( - printf( - spec, - chalk.underline(dep.url), - dep.scale ? dep.scale.current : '✖', - state, - ms(timeNow - dep.created) - ) - ) - if (Array.isArray(dep.instances) && dep.instances.length > 0) { - dep.instances.forEach(i => { - console.log( - printf(` %-${urlLength + 10}s`, ` - ${chalk.underline(i.url)}`) - ) - }) - console.log() - } - }) - console.log() - }) -} diff --git a/bin/now-logout.js b/bin/now-logout.js deleted file mode 100644 index 98bc572..0000000 --- a/bin/now-logout.js +++ /dev/null @@ -1,130 +0,0 @@ -#!/usr/bin/env node - -// Packages -const minimist = require('minimist') -const chalk = require('chalk') -const fetch = require('node-fetch') -const ora = require('ora') - -// Utilities -const cfg = require('../lib/cfg') -const logo = require('../lib/utils/output/logo') -const { handleError } = require('../lib/error') - -const argv = minimist(process.argv.slice(2), { - string: ['config'], - boolean: ['help'], - alias: { - help: 'h', - config: 'c' - } -}) - -const help = () => { - console.log(` - ${chalk.bold(`${logo} now logout`)} - - ${chalk.dim('Options:')} - - -h, --help output usage information - -c ${chalk.bold.underline('FILE')}, --config=${chalk.bold.underline( - 'FILE' - )} config file - - ${chalk.dim('Examples:')} - - ${chalk.gray('–')} Logout from the CLI: - - ${chalk.cyan('$ now logout')} -`) -} - -if (argv.help) { - help() - process.exit(0) -} - -const apiUrl = argv.url || 'https://api.zeit.co' -const endpoint = apiUrl + '/www/user/tokens/' - -if (argv.config) { - cfg.setConfigFile(argv.config) -} - -const requestHeaders = token => ({ - headers: { - Authorization: `bearer ${token}` - } -}) - -const getTokenId = async token => { - const result = await fetch(endpoint, requestHeaders(token)) - const tokenList = await result.json() - - if (!tokenList.tokens) { - return - } - - const tokenInfo = tokenList.tokens.find(t => token === t.token) - - if (!tokenInfo) { - return - } - - return tokenInfo.id -} - -const revokeToken = async (token, tokenId) => { - const details = { - method: 'DELETE' - } - - Object.assign(details, requestHeaders(token)) - const result = await fetch(endpoint + encodeURIComponent(tokenId), details) - - if (!result.ok) { - console.error('Not able to log out') - } -} - -const logout = async () => { - const spinner = ora({ - text: 'Logging out...' - }).start() - - const config = await cfg.read() - - try { - await cfg.removeFile() - } catch (err) { - spinner.fail(`Couldn't remove config while logging out`) - process.exit(1) - } - - let tokenId - - try { - tokenId = await getTokenId(argv.token || config.token) - } catch (err) { - spinner.fail('Not able to get token id on logout') - process.exit(1) - } - - if (!tokenId) { - return - } - - try { - await revokeToken(argv.token || config.token, tokenId) - } catch (err) { - spinner.fail('Could not revoke token on logout') - process.exit(1) - } - - spinner.succeed('Logged out!') -} - -logout().catch(err => { - handleError(err) - process.exit(1) -}) diff --git a/bin/now-logs.js b/bin/now-logs.js deleted file mode 100644 index 3c75123..0000000 --- a/bin/now-logs.js +++ /dev/null @@ -1,290 +0,0 @@ -#!/usr/bin/env node - -const qs = require('querystring') -const minimist = require('minimist') -const chalk = require('chalk') -const dateformat = require('dateformat') -const io = require('socket.io-client') -const Now = require('../lib') -const login = require('../lib/login') -const cfg = require('../lib/cfg') -const { handleError, error } = require('../lib/error') -const logo = require('../lib/utils/output/logo') -const { compare, deserialize } = require('../lib/logs') -const { maybeURL, normalizeURL, parseInstanceURL } = require('../lib/utils/url') - -const argv = minimist(process.argv.slice(2), { - string: ['config', 'query', 'since', 'token', 'until'], - boolean: ['help', 'all', 'debug', 'f'], - alias: { - help: 'h', - all: 'a', - config: 'c', - debug: 'd', - token: 't', - query: 'q' - } -}) - -let deploymentIdOrURL = argv._[0] - -const help = () => { - console.log(` - ${chalk.bold(`${logo} now logs`)} - - ${chalk.dim('Options:')} - - -h, --help output usage information - -a, --all include access logs - -c ${chalk.bold.underline('FILE')}, --config=${chalk.bold.underline( - 'FILE' - )} config file - -d, --debug debug mode [off] - -f wait for additional data [off] - -n ${chalk.bold.underline('NUMBER')} number of logs [1000] - -q ${chalk.bold.underline('QUERY')}, --query=${chalk.bold.underline( - 'QUERY' - )} search query - -t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline( - 'TOKEN' - )} login token - --since=${chalk.bold.underline( - 'SINCE' - )} only return logs after date (ISO 8601) - --until=${chalk.bold.underline( - 'UNTIL' - )} only return logs before date (ISO 8601), ignored if the f option is enbled. - - ${chalk.dim('Examples:')} - - ${chalk.gray('–')} Print logs for the deployment ${chalk.dim( - '`deploymentId`' - )} - - ${chalk.cyan('$ now logs deploymentId')} -`) -} - -if (argv.help || !deploymentIdOrURL) { - help() - process.exit(0) -} - -// Options -const debug = argv.debug -const apiUrl = argv.url || 'https://api.zeit.co' -if (argv.config) { - cfg.setConfigFile(argv.config) -} -const limit = typeof argv.n === 'number' ? argv.n : 1000 -const query = argv.query || '' -const follow = argv.f -const types = argv.all ? [] : ['command', 'stdout', 'stderr', 'exit'] - -let since -try { - since = argv.since ? toSerial(argv.since) : null -} catch (err) { - error(`Invalid date string: ${argv.since}`) - process.exit(1) -} - -let until -try { - until = argv.until ? toSerial(argv.until) : null -} catch (err) { - error(`Invalid date string: ${argv.until}`) - process.exit(1) -} - -let instanceId - -if (maybeURL(deploymentIdOrURL)) { - const normalizedURL = normalizeURL(deploymentIdOrURL) - if (normalizedURL.includes('/')) { - error(`Invalid deployment url: can't include path (${deploymentIdOrURL})`) - process.exit(1) - } - - ;[deploymentIdOrURL, instanceId] = parseInstanceURL(normalizedURL) -} - -Promise.resolve() - .then(async () => { - const config = await cfg.read({ token: argv.token }) - - let token - try { - token = config.token || (await login(apiUrl)) - } catch (err) { - error(`Authentication error – ${err.message}`) - process.exit(1) - } - - await printLogs({ token, config }) - }) - .catch(err => { - handleError(err) - process.exit(1) - }) - -async function printLogs({ token, config: { currentTeam } }) { - let buf = [] - let init = false - let lastLog - - if (!follow) { - onLogs(await fetchLogs({ token, currentTeam, since, until })) - return - } - - const isURL = deploymentIdOrURL.includes('.') - const q = qs.stringify({ - deploymentId: isURL ? '' : deploymentIdOrURL, - host: isURL ? deploymentIdOrURL : '', - instanceId, - types: types.join(','), - query - }) - - const socket = io(`https://log-io.zeit.co?${q}`) - socket.on('connect', () => { - if (debug) { - console.log('> [debug] Socket connected') - } - }) - - socket.on('auth', callback => { - if (debug) { - console.log('> [debug] Socket authenticate') - } - callback(token) - }) - - socket.on('ready', () => { - if (debug) { - console.log('> [debug] Socket ready') - } - - // For the case socket reconnected - const _since = lastLog ? lastLog.serial : since - - fetchLogs({ token, currentTeam, since: _since }).then(logs => { - init = true - const m = {} - logs.concat(buf.map(b => b.log)).forEach(l => { - m[l.id] = l - }) - buf = [] - onLogs(Object.values(m)) - }) - }) - - socket.on('logs', l => { - const log = deserialize(l) - let timer - if (init) { - // Wait for other logs for a while - // and sort them in the correct order - timer = setTimeout(() => { - buf.sort((a, b) => compare(a.log, b.log)) - const idx = buf.findIndex(b => b.log.id === log.id) - buf.slice(0, idx + 1).forEach(b => { - clearTimeout(b.timer) - onLog(b.log) - }) - buf = buf.slice(idx + 1) - }, 300) - } - buf.push({ log, timer }) - }) - - socket.on('disconnect', () => { - if (debug) { - console.log('> [debug] Socket disconnect') - } - init = false - }) - - socket.on('error', err => { - if (debug) { - console.log('> [debug] Socket error', err.stack) - } - }) - - function onLogs(logs) { - logs.sort(compare).forEach(onLog) - } - - function onLog(log) { - lastLog = log - printLog(log) - } -} - -function printLog(log) { - let data - const obj = log.object - if (log.type === 'request') { - data = - `REQ "${obj.method} ${obj.uri} ${obj.protocol}"` + - ` ${obj.remoteAddr} - ${obj.remoteUser || ''}` + - ` "${obj.referer || ''}" "${obj.userAgent}"` - } else if (log.type === 'response') { - data = - `RES "${obj.method} ${obj.uri} ${obj.protocol}"` + - ` ${obj.status} ${obj.bodyBytesSent}` - } else { - data = obj - ? JSON.stringify(obj, null, 2) - : (log.text || '').replace(/\n$/, '') - } - - const date = dateformat(log.date, 'mm/dd hh:MM TT') - - data.split('\n').forEach((line, i) => { - if (i === 0) { - console.log(`${chalk.dim(date)} ${line}`) - } else { - console.log(`${repeat(' ', date.length)} ${line}`) - } - }) -} - -async function fetchLogs({ token, currentTeam, since, until } = {}) { - const now = new Now({ apiUrl, token, debug, currentTeam }) - - let logs - try { - logs = await now.logs(deploymentIdOrURL, { - instanceId, - types, - limit, - query, - since, - until - }) - } catch (err) { - handleError(err) - process.exit(1) - } finally { - now.close() - } - - return logs.map(deserialize) -} - -function repeat(s, n) { - return new Array(n + 1).join(s) -} - -function toSerial(datestr) { - const t = Date.parse(datestr) - if (isNaN(t)) { - throw new TypeError('Invalid date string') - } - - const pidLen = 19 - const seqLen = 19 - return t + repeat('0', pidLen + seqLen) -} diff --git a/bin/now-remove.js b/bin/now-remove.js deleted file mode 100755 index e585128..0000000 --- a/bin/now-remove.js +++ /dev/null @@ -1,218 +0,0 @@ -#!/usr/bin/env node - -// Packages -const minimist = require('minimist') -const chalk = require('chalk') -const ms = require('ms') -const table = require('text-table') - -// Ours -const Now = require('../lib') -const login = require('../lib/login') -const cfg = require('../lib/cfg') -const { handleError, error } = require('../lib/error') -const logo = require('../lib/utils/output/logo') -const { normalizeURL } = require('../lib/utils/url') - -const argv = minimist(process.argv.slice(2), { - string: ['config', 'token'], - boolean: ['help', 'debug', 'hard', 'yes', 'safe'], - alias: { - help: 'h', - config: 'c', - debug: 'd', - token: 't', - yes: 'y' - } -}) - -const ids = argv._ - -// Options -const help = () => { - console.log(` - ${chalk.bold( - `${logo} now remove` - )} deploymentId|deploymentName [...deploymentId|deploymentName] - - ${chalk.dim('Options:')} - - -h, --help Output usage information - -c ${chalk.bold.underline('FILE')}, --config=${chalk.bold.underline( - 'FILE' - )} Config file - -d, --debug Debug mode [off] - -t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline( - 'TOKEN' - )} Login token - -y, --yes Skip confirmation - --safe Skip deployments with an active alias - - ${chalk.dim('Examples:')} - - ${chalk.gray('–')} Remove a deployment identified by ${chalk.dim( - '`deploymentId`' - )}: - - ${chalk.cyan('$ now rm deploymentId')} - - ${chalk.gray('–')} Remove all deployments with name ${chalk.dim('`my-app`')}: - - ${chalk.cyan('$ now rm my-app')} - - ${chalk.gray('–')} Remove two deployments with IDs ${chalk.dim( - '`eyWt6zuSdeus`' - )} and ${chalk.dim('`uWHoA9RQ1d1o`')}: - - ${chalk.cyan('$ now rm eyWt6zuSdeus uWHoA9RQ1d1o')} - - ${chalk.dim('Alias:')} rm -`) -} - -if (argv.help || ids.length === 0) { - help() - process.exit(0) -} - -// Options -const debug = argv.debug -const apiUrl = argv.url || 'https://api.zeit.co' -const hard = argv.hard || false -const skipConfirmation = argv.yes || false - -if (argv.config) { - cfg.setConfigFile(argv.config) -} - -Promise.resolve() - .then(async () => { - const config = await cfg.read({ token: argv.token }) - - let token - try { - token = config.token || (await login(apiUrl)) - } catch (err) { - error(`Authentication error – ${err.message}`) - process.exit(1) - } - - try { - await remove({ token, config }) - } catch (err) { - error(`Unknown error: ${err}\n${err.stack}`) - process.exit(1) - } - }) - .catch(err => { - handleError(err) - process.exit(1) - }) - -function readConfirmation(matches) { - return new Promise(resolve => { - process.stdout.write( - `> The following deployment${matches.length === 1 - ? '' - : 's'} will be removed permanently:\n` - ) - - const tbl = table( - matches.map(depl => { - const time = chalk.gray(ms(new Date() - depl.created) + ' ago') - const url = depl.url ? chalk.underline(`https://${depl.url}`) : '' - return [depl.uid, url, time] - }), - { align: ['l', 'r', 'l'], hsep: ' '.repeat(6) } - ) - process.stdout.write(tbl + '\n') - - for (const depl of matches) { - for (const alias of depl.aliases) { - process.stdout.write( - `> ${chalk.yellow('Warning!')} Deployment ${chalk.bold(depl.uid)} ` + - `is an alias for ${chalk.underline( - `https://${alias.alias}` - )} and will be removed.\n` - ) - } - } - - process.stdout.write( - `${chalk.bold.red('> Are you sure?')} ${chalk.gray('[y/N] ')}` - ) - - process.stdin - .on('data', d => { - process.stdin.pause() - resolve(d.toString().trim()) - }) - .resume() - }) -} - -async function remove({ token, config: { currentTeam } }) { - const now = new Now({ apiUrl, token, debug, currentTeam }) - - const deployments = await now.list() - - let matches = deployments.filter(d => { - return ids.some(id => { - return d.uid === id || d.name === id || d.url === normalizeURL(id) - }) - }) - - const aliases = await Promise.all( - matches.map(depl => now.listAliases(depl.uid)) - ) - - matches = matches.filter((match, i) => { - if (argv.safe && aliases[i].length > 0) { - return false - } - - match.aliases = aliases[i] - return true - }) - - if (matches.length === 0) { - error( - `Could not find ${argv.safe - ? 'unaliased' - : 'any'} deployments matching ${ids - .map(id => chalk.bold(`"${id}"`)) - .join(', ')}. Run ${chalk.dim(`\`now ls\``)} to list.` - ) - return process.exit(1) - } - - try { - if (!skipConfirmation) { - const confirmation = (await readConfirmation(matches)).toLowerCase() - - if (confirmation !== 'y' && confirmation !== 'yes') { - console.log('\n> Aborted') - process.exit(0) - } - } - - const start = new Date() - - await Promise.all(matches.map(depl => now.remove(depl.uid, { hard }))) - - const elapsed = ms(new Date() - start) - console.log(`${chalk.cyan('> Success!')} [${elapsed}]`) - console.log( - table( - matches.map(depl => { - return [`Deployment ${chalk.bold(depl.uid)} removed`] - }) - ) - ) - } catch (err) { - handleError(err) - process.exit(1) - } - - now.close() -} diff --git a/bin/now-scale.js b/bin/now-scale.js deleted file mode 100755 index 94b1c65..0000000 --- a/bin/now-scale.js +++ /dev/null @@ -1,384 +0,0 @@ -#!/usr/bin/env node - -// Packages -const chalk = require('chalk') -const isURL = require('is-url') -const minimist = require('minimist') -const ms = require('ms') -const printf = require('printf') -require('epipebomb')() -const supportsColor = require('supports-color') - -// Ours -const cfg = require('../lib/cfg') -const { handleError, error } = require('../lib/error') -const NowScale = require('../lib/scale') -const login = require('../lib/login') -const exit = require('../lib/utils/exit') -const logo = require('../lib/utils/output/logo') -const info = require('../lib/scale-info') -const sort = require('../lib/sort-deployments') -const success = require('../lib/utils/output/success') - -const argv = minimist(process.argv.slice(2), { - string: ['config', 'token'], - boolean: ['help', 'debug'], - alias: { help: 'h', config: 'c', debug: 'd', token: 't' } -}) - -let id = argv._[0] -const scaleArg = argv._[1] -const optionalScaleArg = argv._[2] - -// Options -const help = () => { - console.log(` - ${chalk.bold(`${logo} now scale`)} ls - ${chalk.bold(`${logo} now scale`)} - ${chalk.bold(`${logo} now scale`)} [max] - - ${chalk.dim('Options:')} - - -h, --help Output usage information - -c ${chalk.bold.underline('FILE')}, --config=${chalk.bold.underline( - 'FILE' - )} Config file - -d, --debug Debug mode [off] - - ${chalk.dim('Examples:')} - - ${chalk.gray('–')} Create a deployment with 3 instances, never sleeps: - - ${chalk.cyan('$ now scale my-deployment-ntahoeato.now.sh 3')} - - ${chalk.gray('–')} Create an automatically scaling deployment: - - ${chalk.cyan('$ now scale my-deployment-ntahoeato.now.sh 1 5')} - - ${chalk.gray( - '–' - )} Create an automatically scaling deployment without specifying max: - - ${chalk.cyan('$ now scale my-deployment-ntahoeato.now.sh 1 auto')} - - ${chalk.gray( - '–' - )} Create an automatically scaling deployment without specifying min or max: - - ${chalk.cyan('$ now scale my-deployment-ntahoeato.now.sh auto')} - - ${chalk.gray( - '–' - )} Create a deployment that is always active and never "sleeps": - - ${chalk.cyan('$ now scale my-deployment-ntahoeato.now.sh 1')} - `) -} - -// Options -const debug = argv.debug -const apiUrl = argv.url || 'https://api.zeit.co' - -if (argv.config) { - cfg.setConfigFile(argv.config) -} - -if (argv.help) { - help() - exit(0) -} else { - Promise.resolve() - .then(async () => { - const config = await cfg.read({ token: argv.token }) - - let token - try { - token = config.token || (await login(apiUrl)) - } catch (err) { - error(`Authentication error – ${err.message}`) - exit(1) - } - - try { - await run({ token, config }) - } catch (err) { - if (err.userError) { - error(err.message) - } else { - error(`Unknown error: ${err}\n${err.stack}`) - } - exit(1) - } - }) - .catch(err => { - handleError(err) - process.exit(1) - }) -} - -function guessParams() { - if (Number.isInteger(scaleArg) && !optionalScaleArg) { - return { min: scaleArg, max: scaleArg } - } else if (Number.isInteger(scaleArg) && Number.isInteger(optionalScaleArg)) { - return { min: scaleArg, max: optionalScaleArg } - } else if (Number.isInteger(scaleArg) && optionalScaleArg === 'auto') { - return { min: scaleArg, max: 'auto' } - } else if ( - (!scaleArg && !optionalScaleArg) || - (scaleArg === 'auto' && !optionalScaleArg) - ) { - return { min: 1, max: 'auto' } - } - help() - process.exit(1) -} - -function isHostNameOrId(str) { - return ( - /(https?:\/\/)?((?:(?=[a-z0-9-]{1,63}\.)(?:xn--)?[a-z0-9]+(?:-[a-z0-9]+)*\.)+[a-z]{2,63})/.test( - str - ) || str.length === 28 - ) -} - -async function run({ token, config: { currentTeam } }) { - const scale = new NowScale({ apiUrl, token, debug, currentTeam }) - const start = Date.now() - - if (id === 'ls') { - await list(scale) - process.exit(0) - } else if (id === 'info') { - await info(scale) - process.exit(0) - } else if (id && isHostNameOrId(id)) { - // Normalize URL by removing slash from the end - if (isURL(id)) { - id = id.replace(/^https:\/\//i, '') - if (id.slice(-1) === '/') { - id = id.slice(0, -1) - } - } - } else { - error('Please specify a deployment: now scale ') - help() - exit(1) - } - - const deployments = await scale.list() - - let match = deployments.find(d => { - // `url` should match the hostname of the deployment - let u = id.replace(/^https:\/\//i, '') - - if (u.indexOf('.') === -1) { - // `.now.sh` domain is implied if just the subdomain is given - u += '.now.sh' - } - return d.uid === id || d.name === id || d.url === u - }) - - if (!match) { - // Maybe it's an alias - const aliasDeployment = (await scale.listAliases()).find( - e => e.alias === id - ) - if (!aliasDeployment) { - error(`Could not find any deployments matching ${id}`) - return process.exit(1) - } - match = deployments.find(d => { - return d.uid === aliasDeployment.deploymentId - }) - } - - const { min, max } = guessParams() - - if ( - !(Number.isInteger(min) || min === 'auto') && - !(Number.isInteger(max) || max === 'auto') - ) { - help() - return exit(1) - } - - if (match.type === 'STATIC') { - if (min === 0 && max === 0) { - error("Static deployments can't be FROZEN. Use `now rm` to remove") - return process.exit(1) - } - console.log('> Static deployments are automatically scaled!') - return process.exit(0) - } - - const { - max: currentMax, - min: currentMin, - current: currentCurrent - } = match.scale - if ( - max === currentMax && - min === currentMin && - Number.isInteger(min) && - currentCurrent >= min && - Number.isInteger(max) && - currentCurrent <= max - ) { - // Nothing to do, let's print the rules - printScaleingRules(match.url, currentCurrent, min, max) - return - } - - if ((match.state === 'FROZEN' || match.scale.current === 0) && min > 0) { - console.log( - `> Deployment is currently in 0 replicas, preparing deployment for scaling...` - ) - if (match.scale.max < 1) { - await scale.setScale(match.uid, { min: 0, max: 1 }) - } - await scale.unfreeze(match) - } - - const { min: newMin, max: newMax } = await scale.setScale(match.uid, { - min, - max - }) - - const elapsed = ms(new Date() - start) - - const currentReplicas = match.scale.current - printScaleingRules(match.url, currentReplicas, newMin, newMax, elapsed) - await info(scale, match.url) - - scale.close() -} -function printScaleingRules(url, currentReplicas, min, max, elapsed) { - const log = console.log - success( - `Configured scaling rules ${chalk.gray(elapsed ? '[' + elapsed + ']' : '')}` - ) - log() - log( - `${chalk.bold(url)} (${chalk.gray(currentReplicas)} ${chalk.gray( - 'current' - )})` - ) - log(printf('%6s %s', 'min', chalk.bold(min))) - log(printf('%6s %s', 'max', chalk.bold(max))) - log(printf('%6s %s', 'auto', chalk.bold(min === max ? '✖' : '✔'))) - log() -} - -async function list(scale) { - let deployments - try { - const app = argv._[1] - deployments = await scale.list(app) - } catch (err) { - handleError(err) - process.exit(1) - } - - scale.close() - - const apps = new Map() - - for (const dep of deployments) { - const deps = apps.get(dep.name) || [] - apps.set(dep.name, deps.concat(dep)) - } - - const sorted = await sort([...apps]) - - const timeNow = new Date() - const urlLength = - deployments.reduce((acc, i) => { - return Math.max(acc, (i.url && i.url.length) || 0) - }, 0) + 5 - - for (const app of sorted) { - const depls = argv.all ? app[1] : app[1].slice(0, 5) - console.log( - `${chalk.bold(app[0])} ${chalk.gray( - '(' + depls.length + ' of ' + app[1].length + ' total)' - )}` - ) - console.log() - const urlSpec = `%-${urlLength}s` - console.log( - printf( - ` ${chalk.grey(urlSpec + ' %8s %8s %8s %8s %8s')}`, - 'url', - 'cur', - 'min', - 'max', - 'auto', - 'age' - ) - ) - for (const instance of depls) { - if (!instance.scale) { - let spec - if (supportsColor) { - spec = ` %-${urlLength + 10}s %8s %8s %8s %8s %8s` - } else { - spec = ` %-${urlLength + 1}s %8s %8s %8s %8s %8s` - } - const infinite = '∞' - console.log( - printf( - spec, - chalk.underline(instance.url), - infinite, - 1, - infinite, - '✔', - ms(timeNow - instance.created) - ) - ) - } else if (instance.scale.current > 0) { - let spec - if (supportsColor) { - spec = ` %-${urlLength + 10}s %8s %8s %8s %8s %8s` - } else { - spec = ` %-${urlLength + 1}s %8s %8s %8s %8s %8s` - } - console.log( - printf( - spec, - chalk.underline(instance.url), - instance.scale.current, - instance.scale.min, - instance.scale.max, - instance.scale.max === instance.scale.min ? '✖' : '✔', - ms(timeNow - instance.created) - ) - ) - } else { - let spec - if (supportsColor) { - spec = ` %-${urlLength + 10}s ${chalk.gray('%8s %8s %8s %8s %8s')}` - } else { - spec = ` %-${urlLength + 1}s ${chalk.gray('%8s %8s %8s %8s %8s')}` - } - console.log( - printf( - spec, - chalk.underline(instance.url), - instance.scale.current, - instance.scale.min, - instance.scale.max, - instance.scale.max === instance.scale.min ? '✖' : '✔', - ms(timeNow - instance.created) - ) - ) - } - } - console.log() - } -} - -process.on('uncaughtException', err => { - handleError(err) - exit(1) -}) diff --git a/bin/now-secrets.js b/bin/now-secrets.js deleted file mode 100755 index 17e93a9..0000000 --- a/bin/now-secrets.js +++ /dev/null @@ -1,297 +0,0 @@ -#!/usr/bin/env node - -// Packages -const chalk = require('chalk') -const table = require('text-table') -const minimist = require('minimist') -const ms = require('ms') - -// Ours -const strlen = require('../lib/strlen') -const cfg = require('../lib/cfg') -const { handleError, error } = require('../lib/error') -const NowSecrets = require('../lib/secrets') -const login = require('../lib/login') -const exit = require('../lib/utils/exit') -const logo = require('../lib/utils/output/logo') - -const argv = minimist(process.argv.slice(2), { - string: ['config', 'token'], - boolean: ['help', 'debug', 'base64'], - alias: { - help: 'h', - config: 'c', - debug: 'd', - base64: 'b', - token: 't' - } -}) - -const subcommand = argv._[0] - -// Options -const help = () => { - console.log(` - ${chalk.bold(`${logo} now secrets`)} - - ${chalk.dim('Options:')} - - -h, --help Output usage information - -b, --base64 Treat value as base64-encoded - -c ${chalk.bold.underline('FILE')}, --config=${chalk.bold.underline( - 'FILE' - )} Config file - -d, --debug Debug mode [off] - -t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline( - 'TOKEN' - )} Login token - - ${chalk.dim('Examples:')} - - ${chalk.gray('–')} Lists all your secrets: - - ${chalk.cyan('$ now secrets ls')} - - ${chalk.gray('–')} Adds a new secret: - - ${chalk.cyan('$ now secrets add my-secret "my value"')} - - ${chalk.gray( - '–' - )} Once added, a secret's value can't be retrieved in plaintext anymore - ${chalk.gray( - '–' - )} If the secret's value is more than one word, wrap it in quotes - ${chalk.gray('–')} Actually, when in doubt, wrap your value in quotes - - ${chalk.gray('–')} Exposes a secret as an env variable: - - ${chalk.cyan(`$ now -e MY_SECRET=${chalk.bold('@my-secret')}`)} - - Notice the ${chalk.cyan.bold( - '`@`' - )} symbol which makes the value a secret reference. - - ${chalk.gray('–')} Renames a secret: - - ${chalk.cyan(`$ now secrets rename my-secret my-renamed-secret`)} - - ${chalk.gray('–')} Removes a secret: - - ${chalk.cyan(`$ now secrets rm my-secret`)} -`) -} - -// Options -const debug = argv.debug -const apiUrl = argv.url || 'https://api.zeit.co' - -if (argv.config) { - cfg.setConfigFile(argv.config) -} - -if (argv.help || !subcommand) { - help() - exit(0) -} else { - Promise.resolve() - .then(async () => { - const config = await cfg.read({ token: argv.token }) - - let token - try { - token = config.token || (await login(apiUrl)) - } catch (err) { - error(`Authentication error – ${err.message}`) - exit(1) - } - - try { - await run({ token, config }) - } catch (err) { - handleError(err) - exit(1) - } - }) - .catch(err => { - handleError(err) - process.exit(1) - }) -} - -async function run({ token, config: { currentTeam, user } }) { - const secrets = new NowSecrets({ apiUrl, token, debug, currentTeam }) - const args = argv._.slice(1) - const start = Date.now() - - if (subcommand === 'ls' || subcommand === 'list') { - if (args.length !== 0) { - error( - `Invalid number of arguments. Usage: ${chalk.cyan('`now secret ls`')}` - ) - return exit(1) - } - - const list = await secrets.ls() - const elapsed = ms(new Date() - start) - - console.log( - `> ${list.length} secret${list.length === 1 - ? '' - : 's'} found under ${chalk.bold( - (currentTeam && currentTeam.slug) || user.username || user.email - )} ${chalk.gray(`[${elapsed}]`)}` - ) - - if (list.length > 0) { - const cur = Date.now() - const header = [['', 'name', 'created'].map(s => chalk.dim(s))] - const out = table( - header.concat( - list.map(secret => { - return [ - '', - chalk.bold(secret.name), - chalk.gray(ms(cur - new Date(secret.created)) + ' ago') - ] - }) - ), - { - align: ['l', 'l', 'l'], - hsep: ' '.repeat(2), - stringLength: strlen - } - ) - - if (out) { - console.log('\n' + out + '\n') - } - } - return secrets.close() - } - - if (subcommand === 'rm' || subcommand === 'remove') { - if (args.length !== 1) { - error( - `Invalid number of arguments. Usage: ${chalk.cyan( - '`now secret rm `' - )}` - ) - return exit(1) - } - const list = await secrets.ls() - const theSecret = list.find(secret => secret.name === args[0]) - - if (theSecret) { - const yes = await readConfirmation(theSecret) - if (!yes) { - error('User abort') - return exit(0) - } - } else { - error(`No secret found by name "${args[0]}"`) - return exit(1) - } - - const secret = await secrets.rm(args[0]) - const elapsed = ms(new Date() - start) - console.log( - `${chalk.cyan('> Success!')} Secret ${chalk.bold( - secret.name - )} removed ${chalk.gray(`[${elapsed}]`)}` - ) - return secrets.close() - } - - if (subcommand === 'rename') { - if (args.length !== 2) { - error( - `Invalid number of arguments. Usage: ${chalk.cyan( - '`now secret rename `' - )}` - ) - return exit(1) - } - const secret = await secrets.rename(args[0], args[1]) - const elapsed = ms(new Date() - start) - console.log( - `${chalk.cyan('> Success!')} Secret ${chalk.bold( - secret.oldName - )} renamed to ${chalk.bold(args[1])} ${chalk.gray(`[${elapsed}]`)}` - ) - return secrets.close() - } - - if (subcommand === 'add' || subcommand === 'set') { - if (args.length !== 2) { - error( - `Invalid number of arguments. Usage: ${chalk.cyan( - '`now secret add `' - )}` - ) - - if (args.length > 2) { - const example = chalk.cyan(`$ now secret add ${args[0]}`) - console.log( - `> If your secret has spaces, make sure to wrap it in quotes. Example: \n ${example} ` - ) - } - - return exit(1) - } - - const [name, value_] = args - let value - - if (argv.base64) { - value = { base64: value_ } - } else { - value = value_ - } - - await secrets.add(name, value) - const elapsed = ms(new Date() - start) - - console.log( - `${chalk.cyan('> Success!')} Secret ${chalk.bold( - name.toLowerCase() - )} added (${chalk.bold( - (currentTeam && currentTeam.slug) || user.username || user.email - )}) ${chalk.gray(`[${elapsed}]`)}` - ) - return secrets.close() - } - - error('Please specify a valid subcommand: ls | add | rename | rm') - help() - exit(1) -} - -process.on('uncaughtException', err => { - handleError(err) - exit(1) -}) - -function readConfirmation(secret) { - return new Promise(resolve => { - const time = chalk.gray(ms(new Date() - new Date(secret.created)) + ' ago') - const tbl = table([[chalk.bold(secret.name), time]], { - align: ['r', 'l'], - hsep: ' '.repeat(6) - }) - - process.stdout.write('> The following secret will be removed permanently\n') - process.stdout.write(' ' + tbl + '\n') - - process.stdout.write( - `${chalk.bold.red('> Are you sure?')} ${chalk.gray('[y/N] ')}` - ) - - process.stdin - .on('data', d => { - process.stdin.pause() - resolve(d.toString().trim().toLowerCase() === 'y') - }) - .resume() - }) -} diff --git a/bin/now-teams.js b/bin/now-teams.js deleted file mode 100644 index eaef587..0000000 --- a/bin/now-teams.js +++ /dev/null @@ -1,171 +0,0 @@ -#!/usr/bin/env node - -// Native -const { resolve } = require('path') - -// Packages -const chalk = require('chalk') -const minimist = require('minimist') - -// Ours -const login = require('../lib/login') -const cfg = require('../lib/cfg') -const error = require('../lib/utils/output/error') -const NowTeams = require('../lib/teams') -const logo = require('../lib/utils/output/logo') -const exit = require('../lib/utils/exit') -const { handleError } = require('../lib/error') - -const argv = minimist(process.argv.slice(2), { - string: ['config', 'token'], - boolean: ['help', 'debug'], - alias: { - help: 'h', - config: 'c', - debug: 'd', - token: 't', - switch: 'change' - } -}) - -const subcommand = argv._[0] - -const help = () => { - console.log(` - ${chalk.bold(`${logo} now teams`)} - - ${chalk.dim('Options:')} - - -h, --help Output usage information - -c ${chalk.bold.underline('FILE')}, --config=${chalk.bold.underline( - 'FILE' - )} Config file - -d, --debug Debug mode [off] - -t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline( - 'TOKEN' - )} Login token - - ${chalk.dim('Examples:')} - - ${chalk.gray('–')} Add a new team: - - ${chalk.cyan('$ now teams add')} - - ${chalk.gray('–')} Switch to a team: - - ${chalk.cyan(`$ now switch `)} - - ${chalk.gray( - '–' - )} If your team's url is 'zeit.co/teams/name', 'name' is the slug - ${chalk.gray('–')} If the slug is omitted, you can choose interactively - - ${chalk.yellow( - 'NOTE:' - )} When you switch, everything you add, list or remove will be scoped that team! - - ${chalk.gray('–')} Invite new members (interactively): - - ${chalk.cyan(`$ now teams invite`)} - - ${chalk.gray('–')} Invite a specific email: - - ${chalk.cyan(`$ now teams invite geist@zeit.co`)} - - ${chalk.gray('–')} Remove a team: - - ${chalk.cyan(`$ now teams rm `)} - - ${chalk.gray('–')} If the id is omitted, you can choose interactively - `) -} - -// Options -const debug = argv.debug -const apiUrl = argv.url || 'https://api.zeit.co' - -if (argv.config) { - cfg.setConfigFile(argv.config) -} - -if (argv.help || !subcommand) { - help() - exit(0) -} else { - Promise.resolve() - .then(async () => { - const config = await cfg.read({ token: argv.token }) - - let token - try { - token = config.token || (await login(apiUrl)) - } catch (err) { - error(`Authentication error – ${err.message}`) - exit(1) - } - - try { - await run({ token, config }) - } catch (err) { - if (err.userError) { - error(err.message) - } else { - error(`Unknown error: ${err.stack}`) - } - exit(1) - } - }) - .catch(err => { - handleError(err) - process.exit(1) - }) -} - -async function run({ token, config: { currentTeam } }) { - const teams = new NowTeams({ apiUrl, token, debug, currentTeam }) - const args = argv._.slice(1) - - switch (subcommand) { - case 'list': - case 'ls': { - await require(resolve(__dirname, 'teams', 'list.js'))({ - teams, - token - }) - break - } - case 'switch': - case 'change': { - await require(resolve(__dirname, 'teams', 'switch.js'))({ - teams, - args, - token - }) - break - } - case 'add': - case 'create': { - await require(resolve(__dirname, 'teams', 'add.js'))({ teams, token }) - break - } - - case 'invite': { - await require(resolve(__dirname, 'teams', 'invite.js'))({ - teams, - args, - token - }) - break - } - - default: { - let code = 0 - if (subcommand !== 'help') { - error('Please specify a valid subcommand: ls | add | rm | set-default') - code = 1 - } - help() - exit(code) - } - } -} diff --git a/bin/now-upgrade.js b/bin/now-upgrade.js deleted file mode 100644 index 55581c9..0000000 --- a/bin/now-upgrade.js +++ /dev/null @@ -1,257 +0,0 @@ -#!/usr/bin/env node - -// Packages -const chalk = require('chalk') -const minimist = require('minimist') -const ms = require('ms') - -// Ours -const login = require('../lib/login') -const cfg = require('../lib/cfg') -const NowPlans = require('../lib/plans') -const indent = require('../lib/indent') -const listInput = require('../lib/utils/input/list') -const code = require('../lib/utils/output/code') -const error = require('../lib/utils/output/error') -const success = require('../lib/utils/output/success') -const cmd = require('../lib/utils/output/cmd') -const logo = require('../lib/utils/output/logo') -const { handleError } = require('../lib/error') - -const { bold } = chalk - -const argv = minimist(process.argv.slice(2), { - string: ['config', 'token'], - boolean: ['help', 'debug'], - alias: { - help: 'h', - config: 'c', - debug: 'd', - token: 't' - } -}) - -const help = () => { - console.log(` - ${chalk.bold(`${logo} now upgrade`)} [plan] - - ${chalk.dim('Options:')} - - -h, --help Output usage information - -c ${chalk.bold.underline('FILE')}, --config=${chalk.bold.underline( - 'FILE' - )} Config file - -d, --debug Debug mode [off] - -t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline( - 'TOKEN' - )} Login token - - ${chalk.dim('Examples:')} - - ${chalk.gray('–')} List available plans and pick one interactively - - ${chalk.cyan('$ now upgrade')} - - ${chalk.yellow('NOTE:')} ${chalk.gray( - 'Make sure you have a payment method, or add one:' - )} - - ${chalk.cyan(`$ now billing add`)} - - ${chalk.gray('–')} Pick a specific plan (premium): - - ${chalk.cyan(`$ now upgrade premium`)} - `) -} - -// Options -const debug = argv.debug -const apiUrl = argv.url || 'https://api.zeit.co' - -if (argv.config) { - cfg.setConfigFile(argv.config) -} - -const exit = code => { - // We give stdout some time to flush out - // because there's a node bug where - // stdout writes are asynchronous - // https://github.com/nodejs/node/issues/6456 - setTimeout(() => process.exit(code || 0), 100) -} - -if (argv.help) { - help() - exit(0) -} else { - Promise.resolve() - .then(async () => { - const config = await cfg.read({ token: argv.token }) - - let token - try { - token = config.token || (await login(apiUrl)) - } catch (err) { - error(`Authentication error – ${err.message}`) - exit(1) - } - - try { - await run({ token, config }) - } catch (err) { - if (err.userError) { - error(err.message) - } else { - error(`Unknown error: ${err.stack}`) - } - exit(1) - } - }) - .catch(err => { - handleError(err) - process.exit(1) - }) -} - -function buildInquirerChoices(current, until) { - if (until) { - until = until.split(' ') - until = ' for ' + chalk.bold(until[0]) + ' more ' + until[1] - } else { - until = '' - } - - const currentText = bold('(current)') - let ossName = `OSS ${bold('FREE')}` - let premiumName = `Premium ${bold('$15')}` - let proName = `Pro ${bold('$50')}` - let advancedName = `Advanced ${bold('$200')}` - - switch (current) { - case 'oss': { - ossName += indent(currentText, 6) - break - } - case 'premium': { - premiumName += indent(currentText, 3) - break - } - case 'pro': { - proName += indent(currentText, 7) - break - } - case 'advanced': { - advancedName += indent(currentText, 1) - break - } - default: { - ossName += indent(currentText, 6) - } - } - - return [ - { - name: ossName, - value: 'oss', - short: `OSS ${bold('FREE')}` - }, - { - name: premiumName, - value: 'premium', - short: `Premium ${bold('$15')}` - }, - { - name: proName, - value: 'pro', - short: `Pro ${bold('$50')}` - }, - { - name: advancedName, - value: 'advanced', - short: `Advanced ${bold('$200')}` - } - ] -} - -async function run({ token, config: { currentTeam, user } }) { - const args = argv._ - if (args.length > 1) { - error('Invalid number of arguments') - return exit(1) - } - - const start = new Date() - const plans = new NowPlans({ apiUrl, token, debug, currentTeam }) - - let planId = args[0] - - if (![undefined, 'oss', 'premium', 'pro', 'advanced'].includes(planId)) { - error(`Invalid plan name – should be ${code('oss')} or ${code('premium')}`) - return exit(1) - } - - const currentPlan = await plans.getCurrent() - - if (planId === undefined) { - const elapsed = ms(new Date() - start) - - let message = `For more info, please head to https://zeit.co` - message = currentTeam - ? `${message}/${currentTeam.slug}/settings/plan` - : `${message}/account/plan` - message += `\n> Select a plan for ${bold( - (currentTeam && currentTeam.slug) || user.username || user.email - )} ${chalk.gray(`[${elapsed}]`)}` - const choices = buildInquirerChoices(currentPlan.id, currentPlan.until) - - planId = await listInput({ - message, - choices, - separator: false, - abort: 'end' - }) - } - - if ( - planId === undefined || - (planId === currentPlan.id && currentPlan.until === undefined) - ) { - return console.log('No changes made') - } - - let newPlan - - try { - newPlan = await plans.set(planId) - } catch (err) { - if (err.code === 'customer_not_found' || err.code === 'source_not_found') { - error( - `You have no payment methods available. Run ${cmd( - 'now billing add' - )} to add one` - ) - } else { - error(`An unknow error occured. Please try again later ${err.message}`) - } - plans.close() - return - } - - if (currentPlan.until && newPlan.id !== 'oss') { - success( - `The cancelation has been undone. You're back on the ${chalk.bold( - `${newPlan.name} plan` - )}` - ) - } else if (newPlan.until) { - success( - `Your plan will be switched to ${chalk.bold( - newPlan.name - )} in ${chalk.bold(newPlan.until)}. Your card will not be charged again` - ) - } else { - success(`You're now on the ${chalk.bold(`${newPlan.name} plan`)}`) - } - - plans.close() -} diff --git a/bin/now-whoami.js b/bin/now-whoami.js deleted file mode 100644 index d94d4c9..0000000 --- a/bin/now-whoami.js +++ /dev/null @@ -1,78 +0,0 @@ -#!/usr/bin/env node - -// Packages -const minimist = require('minimist') -const chalk = require('chalk') - -// Ours -const cfg = require('../lib/cfg') -const exit = require('../lib/utils/exit') -const cmd = require('../lib/utils/output/cmd') -const logo = require('../lib/utils/output/logo') -const { handleError } = require('../lib/error') - -const argv = minimist(process.argv.slice(2), { - string: ['config', 'token'], - boolean: ['help', 'debug', 'all'], - alias: { - help: 'h', - config: 'c', - debug: 'd', - token: 't' - } -}) - -const help = () => { - console.log(` - ${chalk.bold(`${logo} now whoami`)} - - ${chalk.dim('Options:')} - - -h, --help Output usage information - -c ${chalk.bold.underline('FILE')}, --config=${chalk.bold.underline( - 'FILE' - )} Config file - -d, --debug Debug mode [off] - -t ${chalk.bold.underline('TOKEN')}, --token=${chalk.bold.underline( - 'TOKEN' - )} Login token - - ${chalk.dim('Examples:')} - - ${chalk.gray('–')} Show the current team context - - ${chalk.cyan('$ now whoami')} -`) -} - -if (argv.help) { - help() - process.exit(0) -} - -if (argv.config) { - cfg.setConfigFile(argv.config) -} - -async function whoami() { - const config = await cfg.read({ token: argv.token }) - if (!config || !config.token) { - console.log( - `> Not currently logged in! Please run ${cmd('now --login')}.\n` - ) - return exit(1) - } - - if (process.stdout.isTTY) { - process.stdout.write('> ') - } - - const { user } = config - const name = user.username || user.email - console.log(name) -} - -whoami().catch(err => { - handleError(err) - process.exit(1) -}) diff --git a/bin/now.js b/bin/now.js deleted file mode 100755 index 9c6d7c2..0000000 --- a/bin/now.js +++ /dev/null @@ -1,142 +0,0 @@ -#!/usr/bin/env node - -// Native -const { resolve } = require('path') - -// Packages -const updateNotifier = require('update-notifier') -const chalk = require('chalk') - -// Check if the current path exists and throw and error -// if the user is trying to deploy a non-existing path! -// This needs to be done exactly in this place, because -// the utility imports are taking advantage of it -try { - process.cwd() -} catch (err) { - if (err.code === 'ENOENT' && err.syscall === 'uv_cwd') { - console.log(`Current path doesn't exist!`) - } else { - console.log(err) - } - - process.exit(1) -} - -// Utilities -const pkg = require('../lib/pkg') - -if (process.pkg) { - const notifier = updateNotifier({ pkg }) - const update = notifier.update - - if (update) { - let message = `Update available! ${chalk.red( - update.current - )} → ${chalk.green(update.latest)} \n` - message += `${chalk.magenta( - 'Changelog:' - )} https://github.com/zeit/now-cli/releases/tag/${update.latest}\n` - - if (pkg._npmPkg) { - message += `Run ${chalk.magenta('npm i -g now')} to update!` - } else { - message += `Please download binaries from https://zeit.co/download` - } - - notifier.notify({ message }) - } -} - -// This command will be run if no other sub command is specified -const defaultCommand = 'deploy' - -const commands = new Set([ - defaultCommand, - 'help', - 'list', - 'ls', - 'rm', - 'remove', - 'alias', - 'aliases', - 'ln', - 'domain', - 'domains', - 'dns', - 'cert', - 'certs', - 'secret', - 'secrets', - 'cc', - 'billing', - 'upgrade', - 'downgrade', - 'team', - 'teams', - 'switch', - 'log', - 'logs', - 'scale', - 'logout', - 'whoami' -]) - -const aliases = new Map([ - ['ls', 'list'], - ['rm', 'remove'], - ['ln', 'alias'], - ['aliases', 'alias'], - ['domain', 'domains'], - ['cert', 'certs'], - ['secret', 'secrets'], - ['cc', 'billing'], - ['downgrade', 'upgrade'], - ['team', 'teams'], - ['switch', 'teams switch'], - ['log', 'logs'] -]) - -let cmd = defaultCommand -let args = process.argv.slice(2) -const index = args.findIndex(a => commands.has(a)) - -if (index > -1) { - cmd = args[index] - args.splice(index, 1) - - if (cmd === 'help') { - if (index < args.length && commands.has(args[index])) { - cmd = args[index] - args.splice(index, 1) - } else { - cmd = defaultCommand - } - - args.unshift('--help') - } - - cmd = aliases.get(cmd) || cmd - if (cmd.includes(' ')) { - const parts = cmd.split(' ') - cmd = parts.shift() - args = [].concat(parts, args) - } -} - -// Don't throw a useless error message when running `now help help` -// rather show the general help and be useful -if (cmd === 'help') { - cmd = 'deploy' -} else if (cmd === defaultCommand && args[0] === 'login') { - args[0] = '--login' -} - -const bin = resolve(__dirname, 'now-' + cmd + '.js') - -// Prepare process.argv for subcommand -process.argv = process.argv.slice(0, 2).concat(args) - -// Load sub command -// With custom parameter to make "pkg" happy -require(bin, 'may-exclude') diff --git a/bin/teams/add.js b/bin/teams/add.js deleted file mode 100644 index 13cb489..0000000 --- a/bin/teams/add.js +++ /dev/null @@ -1,135 +0,0 @@ -// Packages -const chalk = require('chalk') - -// Ours -const stamp = require('../../lib/utils/output/stamp') -const info = require('../../lib/utils/output/info') -const error = require('../../lib/utils/output/error') -const wait = require('../../lib/utils/output/wait') -const rightPad = require('../../lib/utils/output/right-pad') -const eraseLines = require('../../lib/utils/output/erase-lines') -const { tick } = require('../../lib/utils/output/chars') -const success = require('../../lib/utils/output/success') -const cmd = require('../../lib/utils/output/cmd') -const note = require('../../lib/utils/output/note') -const uid = require('../../lib/utils/output/uid') -const textInput = require('../../lib/utils/input/text') -const exit = require('../../lib/utils/exit') -const cfg = require('../../lib/cfg') - -function validateSlugKeypress(data, value) { - // TODO: the `value` here should contain the current value + the keypress - // should be fixed on utils/input/text.js - return /^[a-zA-Z]+[a-zA-Z0-9_-]*$/.test(value + data) -} - -function gracefulExit() { - console.log() // Blank line - note( - `Your team is now active for all ${cmd('now')} commands!\n Run ${cmd( - 'now switch' - )} to change it in the future.` - ) - return exit() -} - -const teamUrlPrefix = rightPad('Team URL', 14) + chalk.gray('zeit.co/') -const teamNamePrefix = rightPad('Team Name', 14) - -module.exports = async function({ teams, token }) { - let slug - let team - let elapsed - let stopSpinner - - info( - `Pick a team identifier for its url (e.g.: ${chalk.cyan('`zeit.co/acme`')})` - ) - do { - try { - // eslint-disable-next-line no-await-in-loop - slug = await textInput({ - label: `- ${teamUrlPrefix}`, - validateKeypress: validateSlugKeypress, - initialValue: slug, - valid: team, - forceLowerCase: true - }) - } catch (err) { - if (err.message === 'USER_ABORT') { - info('Aborted') - return exit() - } - throw err - } - elapsed = stamp() - stopSpinner = wait(teamUrlPrefix + slug) - - let res - try { - // eslint-disable-next-line no-await-in-loop - res = await teams.create({ slug }) - stopSpinner() - team = res - } catch (err) { - stopSpinner() - eraseLines(2) - error(err.message) - } - } while (!team) - - eraseLines(2) - success(`Team created ${uid(team.id)} ${elapsed()}`) - console.log(chalk.cyan(`${tick} `) + teamUrlPrefix + slug + '\n') - - info('Pick a display name for your team') - let name - try { - name = await textInput({ - label: `- ${teamNamePrefix}`, - validateValue: value => value.trim().length > 0 - }) - } catch (err) { - if (err.message === 'USER_ABORT') { - info('No name specified') - gracefulExit() - } else { - throw err - } - } - elapsed = stamp() - stopSpinner = wait(teamNamePrefix + name) - const res = await teams.edit({ id: team.id, name }) - stopSpinner() - - eraseLines(2) - if (res.error) { - error(res.error.message) - console.log(`${chalk.red(`✖ ${teamNamePrefix}`)}${name}`) - exit(1) - // TODO: maybe we want to ask the user to retry? not sure if - // there's a scenario where that would be wanted - } - - team = Object.assign(team, res) - - success(`Team name saved ${elapsed()}`) - console.log(chalk.cyan(`${tick} `) + teamNamePrefix + team.name + '\n') - - stopSpinner = wait('Saving') - await cfg.merge({ currentTeam: team }) - stopSpinner() - - await require('./invite')({ - teams, - args: [], - token, - introMsg: - 'Invite your team mates! When done, press enter on an empty field', - noopMsg: `You can invite team mates later by running ${cmd( - 'now teams invite' - )}` - }) - - gracefulExit() -} diff --git a/bin/teams/invite.js b/bin/teams/invite.js deleted file mode 100644 index e0c6908..0000000 --- a/bin/teams/invite.js +++ /dev/null @@ -1,160 +0,0 @@ -// Packages -const chalk = require('chalk') - -// Ours -const regexes = require('../../lib/utils/input/regexes') -const wait = require('../../lib/utils/output/wait') -const cfg = require('../../lib/cfg') -const fatalError = require('../../lib/utils/fatal-error') -const cmd = require('../../lib/utils/output/cmd') -const info = require('../../lib/utils/output/info') -const stamp = require('../../lib/utils/output/stamp') -const param = require('../../lib/utils/output/param') -const { tick } = require('../../lib/utils/output/chars') -const rightPad = require('../../lib/utils/output/right-pad') -const textInput = require('../../lib/utils/input/text') -const eraseLines = require('../../lib/utils/output/erase-lines') -const success = require('../../lib/utils/output/success') -const error = require('../../lib/utils/output/error') - -function validateEmail(data) { - return regexes.email.test(data.trim()) || data.length === 0 -} - -const domains = Array.from( - new Set([ - 'aol.com', - 'gmail.com', - 'google.com', - 'yahoo.com', - 'ymail.com', - 'hotmail.com', - 'live.com', - 'outlook.com', - 'inbox.com', - 'mail.com', - 'gmx.com', - 'icloud.com' - ]) -) - -function emailAutoComplete(value, teamSlug) { - const parts = value.split('@') - - if (parts.length === 2 && parts[1].length > 0) { - const [, host] = parts - let suggestion = false - - domains.unshift(teamSlug) - for (const domain of domains) { - if (domain.startsWith(host)) { - suggestion = domain.substr(host.length) - break - } - } - - domains.shift() - return suggestion - } - - return false -} - -module.exports = async function( - { teams, args, token, introMsg, noopMsg = 'No changes made' } = {} -) { - const { user, currentTeam } = await cfg.read({ token }) - - domains.push(user.email.split('@')[1]) - - if (!currentTeam) { - let err = `You can't run this command under ${param( - user.username || user.email - )}.\n` - err += `${chalk.gray('>')} Run ${cmd('now switch')} to choose to a team.` - return fatalError(err) - } - - info(introMsg || `Inviting team members to ${chalk.bold(currentTeam.name)}`) - - if (args.length > 0) { - for (const email of args) { - if (regexes.email.test(email)) { - const stopSpinner = wait(email) - const elapsed = stamp() - // eslint-disable-next-line no-await-in-loop - await teams.inviteUser({ teamId: currentTeam.id, email }) - stopSpinner() - console.log(`${chalk.cyan(tick)} ${email} ${elapsed()}`) - } else { - console.log(`${chalk.red(`✖ ${email}`)} ${chalk.gray('[invalid]')}`) - } - } - return - } - - const inviteUserPrefix = rightPad('Invite User', 14) - const emails = [] - let hasError = false - let email - do { - email = '' - try { - // eslint-disable-next-line no-await-in-loop - email = await textInput({ - label: `- ${inviteUserPrefix}`, - validateValue: validateEmail, - autoComplete: value => emailAutoComplete(value, currentTeam.slug) - }) - } catch (err) { - if (err.message !== 'USER_ABORT') { - throw err - } - } - let elapsed - let stopSpinner - if (email) { - elapsed = stamp() - stopSpinner = wait(inviteUserPrefix + email) - try { - // eslint-disable-next-line no-await-in-loop - await teams.inviteUser({ teamId: currentTeam.id, email }) - stopSpinner() - email = `${email} ${elapsed()}` - emails.push(email) - console.log(`${chalk.cyan(tick)} ${inviteUserPrefix}${email}`) - if (hasError) { - hasError = false - eraseLines(emails.length + 2) - info( - introMsg || - `Inviting team members to ${chalk.bold(currentTeam.name)}` - ) - for (const email of emails) { - console.log(`${chalk.cyan(tick)} ${inviteUserPrefix}${email}`) - } - } - } catch (err) { - stopSpinner() - eraseLines(emails.length + 2) - error(err.message) - hasError = true - for (const email of emails) { - console.log(`${chalk.cyan(tick)} ${inviteUserPrefix}${email}`) - } - } - } - } while (email !== '') - - eraseLines(emails.length + 2) - - const n = emails.length - if (emails.length === 0) { - info(noopMsg) - } else { - success(`Invited ${n} team mate${n > 1 ? 's' : ''}`) - for (const email of emails) { - console.log(`${chalk.cyan(tick)} ${inviteUserPrefix}${email}`) - } - } -} diff --git a/bin/teams/list.js b/bin/teams/list.js deleted file mode 100644 index 0505906..0000000 --- a/bin/teams/list.js +++ /dev/null @@ -1,62 +0,0 @@ -const chalk = require('chalk') - -const wait = require('../../lib/utils/output/wait') -const cfg = require('../../lib/cfg') -const info = require('../../lib/utils/output/info') -const error = require('../../lib/utils/output/error') -const { tick: tickChar } = require('../../lib/utils/output/chars') -const table = require('../../lib/utils/output/table') - -module.exports = async function({ teams, token }) { - const stopSpinner = wait('Fetching teams') - const list = (await teams.ls()).teams - let { user, currentTeam } = await cfg.read({ token }) - const accountIsCurrent = !currentTeam - stopSpinner() - - if (accountIsCurrent) { - currentTeam = { - slug: user.username || user.email - } - } - - const teamList = list.map(({ slug, name }) => { - return { - name, - value: slug, - current: slug === currentTeam.slug ? tickChar : '' - } - }) - - teamList.unshift({ - name: user.email, - value: user.username || user.email, - current: (accountIsCurrent && tickChar) || '' - }) - - // Let's bring the current team to the beginning of the list - if (!accountIsCurrent) { - const index = teamList.findIndex( - choice => choice.value === currentTeam.slug - ) - const choice = teamList.splice(index, 1)[0] - teamList.unshift(choice) - } - - // Printing - const count = teamList.length - if (!count) { - // Maybe should not happen - error(`No team found`) - return - } - - info(`${chalk.bold(count)} team${count > 1 ? 's' : ''} found`) - console.log() - - table( - ['', 'id', 'email / name'], - teamList.map(team => [team.current, team.value, team.name]), - [1, 5] - ) -} diff --git a/bin/teams/switch.js b/bin/teams/switch.js deleted file mode 100644 index 8b9c7f3..0000000 --- a/bin/teams/switch.js +++ /dev/null @@ -1,124 +0,0 @@ -const chalk = require('chalk') - -const wait = require('../../lib/utils/output/wait') -const listInput = require('../../lib/utils/input/list') -const cfg = require('../../lib/cfg') -const exit = require('../../lib/utils/exit') -const success = require('../../lib/utils/output/success') -const info = require('../../lib/utils/output/info') -const error = require('../../lib/utils/output/error') -const param = require('../../lib/utils/output/param') - -async function updateCurrentTeam({ cfg, newTeam } = {}) { - delete newTeam.created - delete newTeam.creator_id - await cfg.merge({ currentTeam: newTeam }) -} - -module.exports = async function({ teams, args, token }) { - let stopSpinner = wait('Fetching teams') - const list = (await teams.ls()).teams - let { user, currentTeam } = await cfg.read({ token }) - const accountIsCurrent = !currentTeam - stopSpinner() - - if (accountIsCurrent) { - currentTeam = { - slug: user.username || user.email - } - } - - if (args.length !== 0) { - const desiredSlug = args[0] - - const newTeam = list.find(team => team.slug === desiredSlug) - if (newTeam) { - await updateCurrentTeam({ cfg, newTeam }) - success(`The team ${chalk.bold(newTeam.name)} is now active!`) - return exit() - } - if (desiredSlug === user.username) { - stopSpinner = wait('Saving') - await cfg.remove('currentTeam') - stopSpinner() - return success(`Your account (${chalk.bold(desiredSlug)}) is now active!`) - } - error(`Could not find membership for team ${param(desiredSlug)}`) - return exit(1) - } - - const choices = list.map(({ slug, name }) => { - name = `${slug} (${name})` - if (slug === currentTeam.slug) { - name += ` ${chalk.bold('(current)')}` - } - - return { - name, - value: slug, - short: slug - } - }) - - const suffix = accountIsCurrent ? ` ${chalk.bold('(current)')}` : '' - - const userEntryName = user.username - ? `${user.username} (${user.email})${suffix}` - : user.email - - choices.unshift({ - name: userEntryName, - value: user.email, - short: user.username - }) - - // Let's bring the current team to the beginning of the list - if (!accountIsCurrent) { - const index = choices.findIndex(choice => choice.value === currentTeam.slug) - const choice = choices.splice(index, 1)[0] - choices.unshift(choice) - } - - let message - - if (currentTeam) { - message = `Switch to:` - } - - const choice = await listInput({ - message, - choices, - separator: false - }) - - // Abort - if (!choice) { - info('No changes made') - return exit() - } - - const newTeam = list.find(item => item.slug === choice) - - // Switch to account - if (!newTeam) { - if (currentTeam.slug === user.username || currentTeam.slug === user.email) { - info('No changes made') - return exit() - } - stopSpinner = wait('Saving') - await cfg.remove('currentTeam') - stopSpinner() - return success(`Your account (${chalk.bold(choice)}) is now active!`) - } - - if (newTeam.slug === currentTeam.slug) { - info('No changes made') - return exit() - } - - stopSpinner = wait('Saving') - await updateCurrentTeam({ cfg, newTeam }) - stopSpinner() - - success(`The team ${chalk.bold(newTeam.name)} is now active!`) -} diff --git a/circle.yml b/circle.yml deleted file mode 100644 index a622420..0000000 --- a/circle.yml +++ /dev/null @@ -1,29 +0,0 @@ -machine: - node: - version: node - -compile: - override: - - npm run pack - post: - - cp packed/* $CIRCLE_ARTIFACTS - -deployment: - default: - branch: /.*/ - owner: zeit - commands: - - node ./scripts/slack.js - release: - tag: /.*/ - owner: zeit - commands: - - ghr -t $GITHUB_TOKEN -u $CIRCLE_PROJECT_USERNAME -r $CIRCLE_PROJECT_REPONAME -replace $CIRCLE_TAG packed - - npm publish - -dependencies: - pre: - - echo "//registry.npmjs.org/:_authToken=$NPM_TOKEN" >> ~/.npmrc - post: - - go get github.com/tcnksm/ghr - - npm install -g slackup diff --git a/download/install.js b/download/install.js deleted file mode 100755 index 1edb664..0000000 --- a/download/install.js +++ /dev/null @@ -1,16 +0,0 @@ -/* eslint-disable no-var */ - -// Native -var path = require('path') -var fs = require('fs') - -var dist = path.join(__dirname, 'dist') -var src = path.join(__dirname, 'src') - -// Don't install when developing locally -if (fs.existsSync(src)) { - // eslint-disable-next-line unicorn/no-process-exit - process.exit(0) -} - -require(path.join(dist, 'download.js')) diff --git a/download/src/chmod.js b/download/src/chmod.js deleted file mode 100644 index 52d8f42..0000000 --- a/download/src/chmod.js +++ /dev/null @@ -1,10 +0,0 @@ -// Native -import fs from 'fs' - -export default function (file) { - const s = fs.statSync(file) - const newMode = s.mode | 64 | 8 | 1 - if (s.mode === newMode) return - const base8 = newMode.toString(8).slice(-3) - fs.chmodSync(file, base8) -} diff --git a/download/src/index.js b/download/src/index.js deleted file mode 100644 index 1191b5c..0000000 --- a/download/src/index.js +++ /dev/null @@ -1,193 +0,0 @@ -/* eslint-disable unicorn/no-process-exit */ - -// Native -import fs from 'fs' -import path from 'path' -import { spawnSync } from 'child_process' -import zlib from 'zlib' - -// Packages -import onDeath from 'death' -import fetch from 'node-fetch' -import retry from 'async-retry' -import which from 'which' - -// Utilities -import plusxSync from './chmod' -import { - disableProgress, - enableProgress, - info, - showProgress, - warn -} from './log' - -fetch.Promise = Promise -global.Promise = Promise -let { platform } = process -if (detectAlpine()) platform = 'alpine' - -const packagePath = path.join(__dirname, '../../package.json') -const packageJSON = JSON.parse(fs.readFileSync(packagePath, 'utf8')) - -const now = path.join(__dirname, 'now') -const targetWin32 = path.join(__dirname, 'now.exe') -const target = platform === 'win32' ? targetWin32 : now -const partial = target + '.partial' -const backup = target + '.' + packageJSON.version + '.backup' - -function whichPromise (name) { - return new Promise((resolve, reject) => { - which(name, (error, result) => { - if (error) return reject(error) - resolve(result) - }) - }) -} - -const platformToName = { - alpine: 'now-alpine', - darwin: 'now-macos', - linux: 'now-linux', - win32: 'now-win.exe' -} - -function detectAlpine () { - if (platform !== 'linux') return false - // https://github.com/sass/node-sass/issues/1589#issuecomment-265292579 - const ldd = spawnSync('ldd', [ process.execPath ]).stdout.toString() - return /\bmusl\b/.test(ldd) -} - -async function download() { - try { - fs.writeFileSync( - now, - '#!/usr/bin/env node\n' + - 'console.log("Please wait until the \'now\' installation completes!")\n' - ) - } catch (err) { - if (err.code === 'EACCES') { - warn( - 'Please try installing now CLI again with the `--unsafe-perm` option.' - ) - info('Example: `npm i -g --unsafe-perm now`') - - process.exit() - } - - throw err - } - - onDeath(() => { - fs.writeFileSync( - now, - '#!/usr/bin/env node\n' + - 'console.log("The \'now\' installation did not complete successfully.")\n' + - 'console.log("Please run \'npm i -g now\' to reinstall!")\n' - ) - process.exit() - }) - - info('For the source code, check out: https://github.com/zeit/now-cli') - - // Print an empty line - console.log('') - - await retry(async () => { - enableProgress('Downloading now CLI ' + packageJSON.version) - showProgress(0) - - try { - const name = platformToName[platform] - const url = `https://cdn.zeit.co/releases/now-cli/${packageJSON.version}/${name}` - const resp = await fetch(url, { compress: false }) - - if (resp.status !== 200) { - throw new Error(resp.statusText + ' ' + url) - } - - const size = resp.headers.get('content-length') - - if (!size) { - throw new Error('Not found (content-length is absent)') - } - - const ws = fs.createWriteStream(partial) - - await new Promise((resolve, reject) => { - let bytesRead = 0 - - resp.body - .on('error', reject) - .on('data', chunk => { - bytesRead += chunk.length - showProgress(100 * bytesRead / size) - }) - - const gunzip = zlib.createGunzip() - - gunzip - .on('error', reject) - - resp.body.pipe(gunzip).pipe(ws) - - ws - .on('error', reject) - .on('close', () => { - showProgress(100) - resolve() - }) - }) - } finally { - disableProgress() - } - }, { - retries: 500, - onRetry: (err) => console.error(err) - }) - - fs.renameSync(partial, target) - fs.writeFileSync(backup, fs.readFileSync(target)) -} - -async function main() { - if (fs.existsSync(backup)) { - fs.writeFileSync(target, fs.readFileSync(backup)) - } else { - await download() - } - - if (platform === 'win32') { - // Now.exe is executed only - fs.unlinkSync(now) - try { - // Workaround for https://github.com/npm/cmd-shim/pull/25 - const globalPath = path.dirname(await whichPromise('npm')) - const gitBashFile = path.join(globalPath, 'now') - fs.writeFileSync( - gitBashFile, - '#!/bin/sh\n' + - 'basedir=$(dirname "$(echo "$0" | sed -e \'s,\\\\,/,g\')")\n' + - '\n' + - 'case `uname` in\n' + - ' *CYGWIN*) basedir=`cygpath -w "$basedir"`;;\n' + - 'esac\n' + - '\n' + - fs.readFileSync(gitBashFile, 'utf8') - ) - } catch (err) { - if (err.code !== 'ENOENT') { - // Not a problem. only git cmd will not work - console.error(err) - } - } - } else { - plusxSync(now) - } -} - -main().catch(err => { - console.error(err) - process.exit(2) -}) diff --git a/download/src/log.js b/download/src/log.js deleted file mode 100644 index aa5e5df..0000000 --- a/download/src/log.js +++ /dev/null @@ -1,43 +0,0 @@ -// Packages -import assert from 'assert' -import chalk from 'chalk' -import Progress from 'progress' - -let bar - -export function enableProgress(text) { - assert(!bar) - - bar = new Progress(`> ${text} [:bar] :percent`, { - stream: process.stdout, - width: 20, - complete: '=', - incomplete: ' ', - total: 100 - }) -} - -export function info(text) { - console.log(`> ${text}`) -} - -export function warn(text) { - console.log(chalk.red('> Warning!'), text) -} - -export function showProgress(percentage) { - assert(bar) - bar.update(percentage / 100) -} - -export function disableProgress() { - assert(bar) - - // It is auto-completed once it updates to 100 - // otherwise it outputs a blank line - if (!bar.complete) { - bar.terminate() - } - - bar = undefined -} diff --git a/download/webpack.js b/download/webpack.js deleted file mode 100644 index b935ed9..0000000 --- a/download/webpack.js +++ /dev/null @@ -1,34 +0,0 @@ -// Native -const path = require('path') - -module.exports = { - target: 'node', - node: { - __dirname: false, - __filename: false, - process: false - }, - entry: [ - './src/index.js' - ], - output: { - path: path.join(__dirname, 'dist'), - filename: 'download.js' - }, - module: { - loaders: [ { - test: /.js$/, - loader: 'babel-loader', - exclude: /node_modules/, - query: { - plugins: [ - 'transform-async-to-generator', - 'transform-runtime' - ], - presets: [ - 'es2015' - ] - } - } ] - } -} diff --git a/lib/agent.js b/lib/agent.js deleted file mode 100644 index 06b31af..0000000 --- a/lib/agent.js +++ /dev/null @@ -1,83 +0,0 @@ -// Native -const { parse } = require('url') -const http = require('http') -const https = require('https') - -// Packages -const fetch = require('node-fetch') - -/** - * Returns a `fetch` version with a similar - * API to the browser's configured with a - * HTTP2 agent. - * - * It encodes `body` automatically as JSON. - * - * @param {String} host - * @return {Function} fetch - */ - -module.exports = class Agent { - constructor(url, { tls = true, debug } = {}) { - this._url = url - const parsed = parse(url) - this._protocol = parsed.protocol - this._debug = debug - if (tls) { - this._initAgent() - } - } - - _initAgent() { - const module = this._protocol === 'https:' ? https : http - this._agent = new module.Agent({ - keepAlive: true, - keepAliveMsecs: 10000, - maxSockets: 8 - }).on('error', err => this._onError(err, this._agent)) - } - - _onError(err, agent) { - if (this._debug) { - console.log(`> [debug] agent connection error ${err}\n${err.stack}`) - } - if (this._agent === agent) { - this._agent = null - } - } - - fetch(path, opts = {}) { - if (!this._agent) { - if (this._debug) { - console.log('> [debug] re-initializing agent') - } - this._initAgent() - } - - const { body } = opts - if (this._agent) { - opts.agent = this._agent - } - - if (body && typeof body === 'object' && typeof body.pipe !== 'function') { - opts.headers['Content-Type'] = 'application/json' - opts.body = JSON.stringify(body) - } - - if (opts.body && typeof body.pipe !== 'function') { - opts.headers['Content-Length'] = Buffer.byteLength(opts.body) - } - - return fetch(this._url + path, opts) - } - - close() { - if (this._debug) { - console.log('> [debug] closing agent') - } - - if (this._agent) { - this._agent.destroy() - } - } -} diff --git a/lib/alias.js b/lib/alias.js deleted file mode 100644 index ccbf6b6..0000000 --- a/lib/alias.js +++ /dev/null @@ -1,881 +0,0 @@ -// Packages -const { readFileSync } = require('fs') -const publicSuffixList = require('psl') -const minimist = require('minimist') -const ms = require('ms') -const chalk = require('chalk') -const { write: copy } = require('clipboardy') - -// Ours -const promptBool = require('../lib/utils/input/prompt-bool') -const info = require('../lib/utils/output/info') -const param = require('../lib/utils/output/param') -const wait = require('../lib/utils/output/wait') -const success = require('../lib/utils/output/success') -const uid = require('../lib/utils/output/uid') -const eraseLines = require('../lib/utils/output/erase-lines') -const stamp = require('../lib/utils/output/stamp') -const error = require('../lib/utils/output/error') -const treatBuyError = require('../lib/utils/domains/treat-buy-error') -const scaleInfo = require('./scale-info') -const { DOMAIN_VERIFICATION_ERROR } = require('./errors') -const isZeitWorld = require('./is-zeit-world') -const resolve4 = require('./dns') -const toHost = require('./to-host') -const exit = require('./utils/exit') -const Now = require('./') - -const argv = minimist(process.argv.slice(2), { - boolean: ['no-clipboard'], - alias: { 'no-clipboard': 'C' } -}) - -const isTTY = process.stdout.isTTY -const clipboard = !argv['no-clipboard'] -const domainRegex = /^((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}$/ - -module.exports = class Alias extends Now { - async ls(deployment) { - if (deployment) { - const target = await this.findDeployment(deployment) - - if (!target) { - const err = new Error( - `Aliases not found by "${deployment}". Run ${chalk.dim( - '`now alias ls`' - )} to see your aliases.` - ) - err.userError = true - throw err - } - - return this.listAliases(target.uid) - } - - return this.listAliases() - } - - async rm(_alias) { - return this.retry(async bail => { - const res = await this._fetch(`/now/aliases/${_alias.uid}`, { - method: 'DELETE' - }) - - if (res.status === 403) { - return bail(new Error('Unauthorized')) - } - - if (res.status !== 200) { - const err = new Error('Deletion failed. Try again later.') - throw err - } - }) - } - - async findDeployment(deployment) { - const list = await this.list() - - let key - let val - - if (/\./.test(deployment)) { - val = toHost(deployment) - key = 'url' - } else { - val = deployment - key = 'uid' - } - - const depl = list.find(d => { - if (d[key] === val) { - if (this._debug) { - console.log(`> [debug] matched deployment ${d.uid} by ${key} ${val}`) - } - - return true - } - - // Match prefix - if (`${val}.now.sh` === d.url) { - if (this._debug) { - console.log(`> [debug] matched deployment ${d.uid} by url ${d.url}`) - } - - return true - } - - return false - }) - - return depl - } - - async updatePathBasedroutes(alias, rules, domains) { - alias = await this.maybeSetUpDomain(alias, domains) - return this.upsertPathAlias(alias, rules) - } - - async upsertPathAlias(alias, rules) { - return this.retry(async (bail, attempt) => { - if (this._debug) { - console.time(`> [debug] /now/aliases #${attempt}`) - } - - const rulesData = this.readRulesFile(rules) - const ruleCount = rulesData.rules.length - const res = await this._fetch(`/now/aliases`, { - method: 'POST', - body: { alias, rules: rulesData.rules } - }) - - const body = await res.json() - body.ruleCount = ruleCount - if (this._debug) { - console.timeEnd(`> [debug] /now/aliases #${attempt}`) - } - - // 409 conflict is returned if it already exists - if (res.status === 409) { - return { uid: body.error.uid } - } - if (res.status === 422) { - return body - } - - // No retry on authorization problems - if (res.status === 403) { - const code = body.error.code - - if (code === 'custom_domain_needs_upgrade') { - const err = new Error( - `Custom domains are only enabled for premium accounts. Please upgrade by running ${chalk.gray( - '`' - )}${chalk.cyan('now upgrade')}${chalk.gray('`')}.` - ) - err.userError = true - return bail(err) - } - - if (code === 'alias_in_use') { - const err = new Error( - `The alias you are trying to configure (${chalk.underline( - chalk.bold(alias) - )}) is already in use by a different account.` - ) - err.userError = true - return bail(err) - } - - if (code === 'forbidden') { - const err = new Error( - 'The domain you are trying to use as an alias is already in use by a different account.' - ) - err.userError = true - return bail(err) - } - - return bail(new Error('Authorization error')) - } - - // All other errors - if (body.error) { - const code = body.error.code - - if (code === 'cert_missing') { - console.log( - `> Provisioning certificate for ${chalk.underline( - chalk.bold(alias) - )}` - ) - - try { - await this.createCert(alias) - } catch (err) { - // We bail to avoid retrying the whole process - // of aliasing which would involve too many - // retries on certificate provisioning - return bail(err) - } - - // Try again, but now having provisioned the certificate - return this.upsertPathAlias(alias, rules) - } - - if (code === 'cert_expired') { - console.log( - `> Renewing certificate for ${chalk.underline(chalk.bold(alias))}` - ) - - try { - await this.createCert(alias, { renew: true }) - } catch (err) { - return bail(err) - } - } - - return bail(new Error(body.error.message)) - } - - // The two expected succesful cods are 200 and 304 - if (res.status !== 200 && res.status !== 304) { - throw new Error('Unhandled error') - } - - return body - }) - } - - readRulesFile(rules) { - try { - const rulesJson = readFileSync(rules, 'utf8') - return JSON.parse(rulesJson) - } catch (err) { - console.error(`Reading rules file ${rules} failed: ${err}`) - } - } - - async set(deployment, alias, domains, currentTeam, user) { - alias = alias.replace(/^https:\/\//i, '') - - if (alias.indexOf('.') === -1) { - // `.now.sh` domain is implied if just the subdomain is given - alias += '.now.sh' - } - const depl = await this.findDeployment(deployment) - if (!depl) { - const err = new Error( - `Deployment not found by "${deployment}". Run ${chalk.dim( - '`now ls`' - )} to see your deployments.` - ) - err.userError = true - throw err - } - - const aliasDepl = (await this.listAliases()).find(e => e.alias === alias) - if (aliasDepl && aliasDepl.rules) { - if (isTTY) { - try { - const msg = - `> Path alias exists with ${aliasDepl.rules.length} rule${aliasDepl - .rules.length > 1 - ? 's' - : ''}.\n` + - `> Are you sure you want to update ${alias} to be a normal alias?\n` - - const confirmation = await promptBool(msg, { - trailing: '\n' - }) - - if (!confirmation) { - info('Aborted') - return exit(1) - } - } catch (err) { - console.log(err) - } - } else { - console.log( - `Overwriting path alias with ${aliasDepl.rules.length} rule${aliasDepl - .rules.length > 1 - ? 's' - : ''} to be a normal alias.` - ) - } - } - - let aliasedDeployment = null - let shouldScaleDown = false - - if (aliasDepl && depl.scale) { - aliasedDeployment = await this.findDeployment(aliasDepl.deploymentId) - if ( - aliasedDeployment && - aliasedDeployment.scale && - aliasedDeployment.scale.current >= depl.scale.current && - (aliasedDeployment.scale.min > depl.scale.min || - aliasedDeployment.scale.max > depl.scale.max) - ) { - shouldScaleDown = true - console.log( - `> Alias ${alias} points to ${chalk.bold( - aliasedDeployment.url - )} (${chalk.bold(aliasedDeployment.scale.current + ' instances')})` - ) - // Test if we need to change the scale or just update the rules - console.log( - `> Scaling ${depl.url} to ${chalk.bold( - aliasedDeployment.scale.current + ' instances' - )} atomically` // Not a typo - ) - if (depl.scale.current !== aliasedDeployment.scale.current) { - if (depl.scale.max < 1) { - if (this._debug) { - console.log( - 'Updating max scale to 1 so that deployment may be unfrozen.' - ) - } - await this.setScale(depl.uid, { - min: depl.scale.min, - max: Math.max(aliasedDeployment.scale.max, 1) - }) - } - if (depl.scale.current < 1) { - if (this._debug) { - console.log(`> Deployment ${depl.url} is frozen, unfreezing...`) - } - await this.unfreeze(depl) - if (this._debug) { - console.log( - `> Deployment is now unfrozen, scaling it to match current instance count` - ) - } - } - // Scale it to current limit - if (depl.scale.current !== aliasedDeployment.scale.current) { - if (this._debug) { - console.log(`> Scaling deployment to match current scale.`) - } - await this.setScale(depl.uid, { - min: aliasedDeployment.scale.current, - max: aliasedDeployment.scale.current - }) - } - await scaleInfo(this, depl.url) - if (this._debug) { - console.log(`> Updating scaling rules for deployment.`) - } - } - - await this.setScale(depl.uid, { - min: Math.max(aliasedDeployment.scale.min, depl.scale.min), - max: Math.max(aliasedDeployment.scale.max, depl.scale.max) - }) - } - } - - alias = await this.maybeSetUpDomain(alias, domains, currentTeam, user) - - const aliasTime = Date.now() - const newAlias = await this.createAlias(depl, alias) - if (!newAlias) { - throw new Error( - `Unexpected error occurred while setting up alias: ${JSON.stringify( - newAlias - )}` - ) - } - const { created, uid } = newAlias - if (created) { - const output = `${chalk.cyan( - '> Success!' - )} ${alias} now points to ${chalk.bold(depl.url)}! ${chalk.grey( - '[' + ms(Date.now() - aliasTime) + ']' - )}` - if (isTTY && clipboard) { - try { - await copy(depl.url) - } catch (err) { - } finally { - console.log(output) - } - } else { - console.log(output) - } - } else { - console.log( - `${chalk.cyan('> Success!')} Alias already exists ${chalk.dim( - `(${uid})` - )}.` - ) - } - if (aliasedDeployment && shouldScaleDown) { - const scaleDown = Date.now() - await this.setScale(aliasedDeployment.uid, { min: 0, max: 1 }) - console.log( - `> Scaled ${chalk.gray( - aliasedDeployment.url - )} down to 1 instance ${chalk.gray( - '[' + ms(Date.now() - scaleDown) + ']' - )}` - ) - } - } - - createAlias(depl, alias) { - return this.retry(async (bail, attempt) => { - if (this._debug) { - console.time( - `> [debug] /now/deployments/${depl.uid}/aliases #${attempt}` - ) - } - - const res = await this._fetch(`/now/deployments/${depl.uid}/aliases`, { - method: 'POST', - body: { alias } - }) - - const body = await res.json() - if (this._debug) { - console.timeEnd( - `> [debug] /now/deployments/${depl.uid}/aliases #${attempt}` - ) - } - - // 409 conflict is returned if it already exists - if (res.status === 409) { - return { uid: body.error.uid } - } - - // No retry on authorization problems - if (res.status === 403) { - const code = body.error.code - - if (code === 'custom_domain_needs_upgrade') { - const err = new Error( - `Custom domains are only enabled for premium accounts. Please upgrade by running ${chalk.gray( - '`' - )}${chalk.cyan('now upgrade')}${chalk.gray('`')}.` - ) - err.userError = true - return bail(err) - } - - if (code === 'alias_in_use') { - const err = new Error( - `The alias you are trying to configure (${chalk.underline( - chalk.bold(alias) - )}) is already in use by a different account.` - ) - err.userError = true - return bail(err) - } - - if (code === 'forbidden') { - const err = new Error( - 'The domain you are trying to use as an alias is already in use by a different account.' - ) - err.userError = true - return bail(err) - } - - return bail(new Error('Authorization error')) - } - - // All other errors - if (body.error) { - const code = body.error.code - - if (code === 'deployment_not_found') { - return bail(new Error('Deployment not found')) - } - - if (code === 'cert_missing') { - console.log( - `> Provisioning certificate for ${chalk.underline( - chalk.bold(alias) - )}` - ) - - try { - await this.createCert(alias) - } catch (err) { - // We bail to avoid retrying the whole process - // of aliasing which would involve too many - // retries on certificate provisioning - return bail(err) - } - - // Try again, but now having provisioned the certificate - return this.createAlias(depl, alias) - } - - if (code === 'cert_expired') { - console.log( - `> Renewing certificate for ${chalk.underline(chalk.bold(alias))}` - ) - - try { - await this.createCert(alias, { renew: true }) - } catch (err) { - return bail(err) - } - } - - return bail(new Error(body.error.message)) - } - - // The two expected succesful cods are 200 and 304 - if (res.status !== 200 && res.status !== 304) { - throw new Error('Unhandled error') - } - - return body - }) - } - - async setupRecord(domain, name) { - await this.setupDomain(domain) - - if (this._debug) { - console.log(`> [debug] Setting up record "${name}" for "${domain}"`) - } - - const type = name === '' ? 'ALIAS' : 'CNAME' - return this.retry(async (bail, attempt) => { - if (this._debug) { - console.time(`> [debug] /domains/${domain}/records #${attempt}`) - } - - const res = await this._fetch(`/domains/${domain}/records`, { - method: 'POST', - body: { type, name: name === '' ? name : '*', value: 'alias.zeit.co' } - }) - - if (this._debug) { - console.timeEnd(`> [debug] /domains/${domain}/records #${attempt}`) - } - - if (res.status === 403) { - return bail(new Error('Unauthorized')) - } - - const body = await res.json() - - if (res.status !== 200) { - throw new Error(body.error.message) - } - - return body - }) - } - - async maybeSetUpDomain(alias, domains, currentTeam, user) { - const gracefulExit = () => { - this.close() - domains.close() - // eslint-disable-next-line unicorn/no-process-exit - process.exit() - } - // Make alias lowercase - alias = alias.toLowerCase() - - // Trim leading and trailing dots - // for example: `google.com.` => `google.com` - alias = alias.replace(/^\.+/, '').replace(/\.+$/, '') - // Evaluate the alias - if (/\./.test(alias)) { - alias = toHost(alias) - } else { - if (this._debug) { - console.log(`> [debug] suffixing \`.now.sh\` to alias ${alias}`) - } - - alias = `${alias}.now.sh` - } - - if (!domainRegex.test(alias)) { - const err = new Error(`Invalid alias "${alias}"`) - err.userError = true - throw err - } - - if (!/\.now\.sh$/.test(alias)) { - console.log(`> ${chalk.bold(chalk.underline(alias))} is a custom domain.`) - - let stopSpinner = wait('Fetching domain info') - - let elapsed = stamp() - const parsed = publicSuffixList.parse(alias) - const pricePromise = domains.price(parsed.domain).catch(() => { - // Can be safely ignored - }) - const canBePurchased = await domains.status(parsed.domain) - const aliasParam = param(parsed.domain) - let price - let period - - stopSpinner() - - if (canBePurchased) { - try { - const json = await pricePromise - price = json.price - period = json.period - } catch (err) { - // Can be safely ignored - } - } - if (canBePurchased && price && period) { - const periodMsg = `${period}yr${period > 1 ? 's' : ''}` - info( - `The domain ${aliasParam} is ${chalk.italic( - 'available' - )} to buy under ${chalk.bold( - (currentTeam && currentTeam.slug) || user.username || user.email - )}! ${elapsed()}` - ) - const confirmation = await promptBool( - `Buy now for ${chalk.bold(`$${price}`)} (${periodMsg})?` - ) - eraseLines(1) - if (!confirmation) { - info('Aborted') - gracefulExit() - } - elapsed = stamp() - stopSpinner = wait('Purchasing') - let domain - try { - domain = await domains.buy(parsed.domain) - } catch (err) { - stopSpinner() - treatBuyError(err) - gracefulExit() - } - - stopSpinner() - success(`Domain purchased and created ${uid(domain.uid)} ${elapsed()}`) - - stopSpinner = wait('Verifying nameservers') - - let domainInfo - - try { - domainInfo = await this.setupDomain(parsed.domain) - } catch (err) { - if (this._debug) { - console.log('> [debug] Error while trying to setup the domain', err) - } - } - - stopSpinner() - - if (!domainInfo.verified) { - const tld = param(`.${parsed.tld}`) - error( - 'The nameservers are pending propagation. Please try again shortly' - ) - info( - `The ${tld} servers might take some extra time to reflect changes` - ) - gracefulExit() - } - } - - console.log( - `> Verifying the DNS settings for ${chalk.bold( - chalk.underline(alias) - )} (see ${chalk.underline('https://zeit.world')} for help)` - ) - - const _domain = publicSuffixList.parse(alias).domain - let _domainInfo - try { - _domainInfo = await this.getDomain(_domain) - } catch (err) { - if (err.status === 404) { - // It's ok if the domain was not found – we'll add it when creating - // the alias - } else { - throw err - } - } - const domainInfo = - _domainInfo && !_domainInfo.error ? _domainInfo : undefined - const { domain, nameservers } = domainInfo - ? { domain: _domain } - : await this.getNameservers(alias) - const usingZeitWorld = domainInfo - ? !domainInfo.isExternal - : isZeitWorld(nameservers) - let skipDNSVerification = false - - if (this._debug) { - if (domainInfo) { - console.log( - `> [debug] Found domain ${domain} with verified:${domainInfo.verified}` - ) - } else { - console.log( - `> [debug] Found domain ${domain} and nameservers ${nameservers}` - ) - } - } - - if (!usingZeitWorld && domainInfo) { - if (domainInfo.verified) { - skipDNSVerification = true - } else if (domainInfo.uid) { - const { verified, created } = await this.setupDomain(domain, { - isExternal: true - }) - if (!(created && verified)) { - const e = new Error( - `> Failed to verify the ownership of ${domain}, please refer to 'now domain --help'.` - ) - e.userError = true - throw e - } - console.log( - `${chalk.cyan('> Success!')} Domain ${chalk.bold( - chalk.underline(domain) - )} verified` - ) - } - } - - try { - if (!skipDNSVerification) { - await this.verifyOwnership(alias) - } - } catch (err) { - if (err.userError) { - // A user error would imply that verification failed - // in which case we attempt to correct the dns - // configuration (if we can!) - try { - if (usingZeitWorld) { - console.log( - `> Detected ${chalk.bold( - chalk.underline('zeit.world') - )} nameservers! Configuring records.` - ) - const record = alias.substr(0, alias.length - domain.length) - - // Lean up trailing and leading dots - const _record = record.replace(/^\./, '').replace(/\.$/, '') - const _domain = domain.replace(/^\./, '').replace(/\.$/, '') - - if (_record === '') { - await this.setupRecord(_domain, '*') - } - - await this.setupRecord(_domain, _record) - - this.recordSetup = true - console.log('> DNS Configured! Verifying propagation…') - - try { - await this.retry(() => this.verifyOwnership(alias), { - retries: 10, - maxTimeout: 8000 - }) - } catch (err2) { - const e = new Error( - '> We configured the DNS settings for your alias, but we were unable to ' + - "verify that they've propagated. Please try the alias again later." - ) - e.userError = true - throw e - } - } else { - console.log( - `> Resolved IP: ${err.ip - ? `${chalk.underline(err.ip)} (unknown)` - : chalk.dim('none')}` - ) - console.log( - `> Nameservers: ${nameservers && nameservers.length - ? nameservers.map(ns => chalk.underline(ns)).join(', ') - : chalk.dim('none')}` - ) - throw err - } - } catch (e) { - if (e.userError) { - throw e - } - - throw err - } - } else { - throw err - } - } - - if (!usingZeitWorld && !skipDNSVerification) { - if (this._debug) { - console.log( - `> [debug] Trying to register a non-ZeitWorld domain ${domain} for the current user` - ) - } - - const { uid, verified, created } = await this.setupDomain(domain, { - isExternal: true - }) - if (!(created && verified)) { - const e = new Error( - `> Failed to verify the ownership of ${domain}, please refer to 'now domain --help'.` - ) - e.userError = true - throw e - } - console.log( - `${chalk.cyan('> Success!')} Domain ${chalk.bold( - chalk.underline(domain) - )} ${chalk.dim(`(${uid})`)} added` - ) - } - - console.log(`> Verification ${chalk.bold('OK')}!`) - } - return alias - } - - verifyOwnership(domain) { - return this.retry( - async bail => { - const targets = await resolve4('alias.zeit.co') - - if (targets.length <= 0) { - return bail(new Error('Unable to resolve alias.zeit.co')) - } - - let ips = [] - - try { - ips = await resolve4(domain) - } catch (err) { - if ( - err.code === 'ENODATA' || - err.code === 'ESERVFAIL' || - err.code === 'ENOTFOUND' - ) { - // Not errors per se, just absence of records - if (this._debug) { - console.log(`> [debug] No records found for "${domain}"`) - } - - const err = new Error(DOMAIN_VERIFICATION_ERROR) - err.userError = true - return bail(err) - } - throw err - } - - if (ips.length <= 0) { - const err = new Error(DOMAIN_VERIFICATION_ERROR) - err.userError = true - return bail(err) - } - - for (const ip of ips) { - if (targets.indexOf(ip) === -1) { - const err = new Error( - `The domain ${domain} has an A record ${chalk.bold( - ip - )} that doesn't resolve to ${chalk.bold( - chalk.underline('alias.zeit.co') - )}.\n> ` + DOMAIN_VERIFICATION_ERROR - ) - err.ip = ip - err.userError = true - return bail(err) - } - } - }, - { retries: 5 } - ) - } -} diff --git a/lib/build-logger.js b/lib/build-logger.js deleted file mode 100644 index 8479f08..0000000 --- a/lib/build-logger.js +++ /dev/null @@ -1,138 +0,0 @@ -// Native -const EventEmitter = require('events') - -// Packages -const io = require('socket.io-client') -const chalk = require('chalk') - -const { compare, deserialize } = require('./logs') - -module.exports = class Logger extends EventEmitter { - constructor(host, token, { debug = false, quiet = false } = {}) { - super() - this.host = host - this.token = token - this.debug = debug - this.quiet = quiet - - // ReadyState - this.building = false - - this.socket = io(`https://io.now.sh/states?host=${host}&v=2`) - this.socket.once('error', this.onSocketError.bind(this)) - this.socket.on('auth', this.onAuth.bind(this)) - this.socket.on('state', this.onState.bind(this)) - this.socket.on('logs', this.onLog.bind(this)) - this.socket.on('backend', this.onComplete.bind(this)) - - // Log buffer - this.buf = [] - this.printed = new Set() - } - - onAuth(callback) { - if (this.debug) { - console.log('> [debug] authenticate') - } - callback(this.token) - } - - onState(state) { - // Console.log(state) - if (!state.id) { - console.error('> Deployment not found') - this.emit('error') - return - } - - if (state.error) { - this.emit('error', state) - return - } - - if (state.backend) { - this.onComplete() - return - } - - if (state.logs) { - state.logs.forEach(this.onLog, this) - } - } - - onLog(log) { - if (!this.building) { - if (!this.quiet) { - console.log('> Building') - } - this.building = true - } - - if (this.quiet) { - return - } - - log = deserialize(log) - - const timer = setTimeout(() => { - this.buf.sort((a, b) => compare(a.log, b.log)) - const idx = this.buf.findIndex(b => b.log.id === log.id) + 1 - for (const b of this.buf.slice(0, idx)) { - clearTimeout(b.timer) - this.printLog(b.log) - } - this.buf = this.buf.slice(idx) - }, 500) - - this.buf.push({ log, timer }) - } - - onComplete() { - this.socket.disconnect() - - if (this.building) { - this.building = false - } - - this.buf.sort((a, b) => compare(a.log, b.log)) - - // Flush all buffer - for (const b of this.buf) { - clearTimeout(b.timer) - this.printLog(b.log) - } - this.buf = [] - - this.emit('close') - } - - onSocketError(err) { - if (this.debug) { - console.log(`> [debug] Socket error ${err}\n${err.stack}`) - } - } - - printLog(log) { - if (this.printed.has(log.id)) return - - this.printed.add(log.id) - - const data = log.object ? JSON.stringify(log.object) : log.text - - if (log.type === 'command') { - console.log(`${chalk.gray('>')} ▲ ${data}`) - } else if (log.type === 'stderr') { - data.split('\n').forEach(v => { - if (v.length > 0) { - console.error(chalk.gray(`> ${v}`)) - } - }) - } else if (log.type === 'stdout') { - data.split('\n').forEach(v => { - if (v.length > 0) { - console.log(`${chalk.gray('>')} ${v}`) - } - }) - } - } -} diff --git a/lib/certs.js b/lib/certs.js deleted file mode 100644 index 5d6916e..0000000 --- a/lib/certs.js +++ /dev/null @@ -1,101 +0,0 @@ -// Ours -const Now = require('../lib') - -module.exports = class Certs extends Now { - ls() { - return this.retry(async (bail, attempt) => { - if (this._debug) { - console.time(`> [debug] #${attempt} GET now/certs`) - } - - const res = await this._fetch('/now/certs') - - if (this._debug) { - console.timeEnd(`> [debug] #${attempt} GET now/certs`) - } - - const body = await res.json() - return body.certs - }) - } - - create(cn) { - return this.createCert(cn) - } - - renew(cn) { - return this.createCert(cn, { renew: true }) - } - - put(cn, crt, key, ca) { - return this.retry(async (bail, attempt) => { - if (this._debug) { - console.time(`> [debug] #${attempt} PUT now/certs`) - } - - const res = await this._fetch('/now/certs', { - method: 'PUT', - body: { - domains: [cn], - ca, - cert: crt, - key - } - }) - - if (this._debug) { - console.timeEnd(`> [debug] #${attempt} PUT now/certs`) - } - - if (res.status === 403) { - return bail(new Error('Unauthorized')) - } - - const body = await res.json() - - if (res.status !== 200) { - if (res.status === 404 || res.status === 400) { - const err = new Error(body.error.message) - err.userError = true - return bail(err) - } - - throw new Error(body.error.message) - } - - return body - }) - } - - delete(cn) { - return this.retry(async (bail, attempt) => { - if (this._debug) { - console.time(`> [debug] #${attempt} DELETE now/certs/${cn}`) - } - - const res = await this._fetch(`/now/certs/${cn}`, { method: 'DELETE' }) - - if (this._debug) { - console.timeEnd(`> [debug] #${attempt} DELETE now/certs/${cn}`) - } - - if (res.status === 403) { - return bail(new Error('Unauthorized')) - } - - const body = await res.json() - - if (res.status !== 200) { - if (res.status === 404 || res.status === 400) { - const err = new Error(body.error.message) - err.userError = true - return bail(err) - } - - throw new Error(body.error.message) - } - - return body - }) - } -} diff --git a/lib/cfg.js b/lib/cfg.js deleted file mode 100644 index bd213cb..0000000 --- a/lib/cfg.js +++ /dev/null @@ -1,112 +0,0 @@ -// Native -const { homedir } = require('os') -const path = require('path') - -// Packages -const fs = require('fs-extra') -const ms = require('ms') - -// Ours -const { get: getUser } = require('./user') - -// `8h` is arbitrarily used based on the average sleep time -const TTL = ms('8h') - -let file = process.env.NOW_JSON - ? path.resolve(process.env.NOW_JSON) - : path.resolve(homedir(), '.now.json') - -function setConfigFile(nowjson) { - file = path.resolve(nowjson) -} - -function save(data) { - fs.writeFileSync(file, JSON.stringify(data, null, 2)) -} - -/** - * Reads the config file - * - * Optionally, always queries the API to get the user info even if the - * config file is not present - * - * @param {Boolean} force [false] Queries the API even if the config - * file is not present. If `true`, `token` - * *must* be specified - * @param {String} token Will be used to autenticate in the API - if needed - * @param {String} apiUrl URL of the API to be used - * @return {Object} - */ -async function read({ force = false, token, apiUrl } = {}) { - let existing = {} - try { - existing = fs.readFileSync(file, 'utf8') - existing = JSON.parse(existing) - } catch (err) {} - - // Will happen if `force`d or if `--token` is used and it's different from - // The one that's stored (which can be `undefined`) - if ((force && token) || (token && token !== existing.token)) { - const user = await getUser({ token, apiUrl }) - if (user) { - return { - token, - user: { - uid: user.uid, - username: user.username, - email: user.email - }, - currentTeam: existing.currentTeam - } - } - return {} - } - - if (!existing.token) { - return {} - } - - if (!existing.lastUpdate || Date.now() - existing.lastUpdate > TTL) { - // TODO: update `teams` info - const token = existing.token - const user = await getUser({ token }) - - if (user) { - existing.user = user - existing.lastUpdate = Date.now() - save(existing) - } - } - return existing -} - -/** - * Merges the `data` object onto the - * JSON config stored in `.now.json`. - * - * (atomic) - * @param {Object} data - */ -async function merge(data) { - const cfg = Object.assign({}, await read(), data) - save(cfg) -} - -// Removes a key from the config and store the result -async function remove(key) { - const cfg = await read() - delete cfg[key] - fs.writeFileSync(file, JSON.stringify(cfg, null, 2)) -} - -// We need to remove the config file when running `now logout` -const removeFile = async () => fs.remove(file) - -module.exports = { - setConfigFile, - read, - merge, - remove, - removeFile -} diff --git a/lib/credit-cards.js b/lib/credit-cards.js deleted file mode 100644 index 7feff52..0000000 --- a/lib/credit-cards.js +++ /dev/null @@ -1,73 +0,0 @@ -const stripe = require('stripe')('pk_live_alyEi3lN0kSwbdevK0nrGwTw') - -const Now = require('../lib') - -module.exports = class CreditCards extends Now { - async ls() { - const res = await this._fetch('/cards') - const body = await res.json() - if (res.status !== 200) { - const e = new Error(body.error.message) - e.code = body.error.code - throw e - } - return body - } - - async setDefault(cardId) { - await this._fetch('/cards/default', { - method: 'PUT', - body: { cardId } - }) - return true - } - - async rm(cardId) { - await this._fetch(`/cards/${encodeURIComponent(cardId)}`, { - method: 'DELETE' - }) - return true - } - - /* eslint-disable camelcase */ - add(card) { - return new Promise(async (resolve, reject) => { - const expDateParts = card.expDate.split(' / ') - card = { - name: card.name, - number: card.cardNumber, - cvc: card.ccv, - address_country: card.country, - address_zip: card.zipCode, - address_state: card.state, - address_city: card.city, - address_line1: card.address1 - } - - card.exp_month = expDateParts[0] - card.exp_year = expDateParts[1] - - try { - const stripeToken = (await stripe.tokens.create({ card })).id - const res = await this._fetch('/cards', { - method: 'POST', - body: { stripeToken } - }) - - const body = await res.json() - - if (body && body.id) { - resolve({ - last4: body.last4 - }) - } else if (body.error && body.error.message) { - reject(new Error(body.error.message)) - } else { - reject(new Error('Unknown error')) - } - } catch (err) { - reject(new Error(err.message || 'Unknown error')) - } - }) - } -} diff --git a/lib/dns.js b/lib/dns.js deleted file mode 100644 index 124840a..0000000 --- a/lib/dns.js +++ /dev/null @@ -1,15 +0,0 @@ -// Packages -const dns = require('dns') - -function resolve4(host) { - return new Promise((resolve, reject) => { - return dns.resolve4(host, (err, answer) => { - if (err) { - return reject(err) - } - - resolve(answer) - }) - }) -} -module.exports = resolve4 diff --git a/lib/domain-records.js b/lib/domain-records.js deleted file mode 100644 index a6a86c2..0000000 --- a/lib/domain-records.js +++ /dev/null @@ -1,148 +0,0 @@ -// Ours -const Now = require('../lib') - -module.exports = class DomainRecords extends Now { - async getRecord(id) { - const all = (await this.ls()).entries() - for (const [domain, records] of all) { - for (const record of records) { - if (record.id === id) { - record.domain = domain - return record - } - } - } - return null - } - - async ls(dom) { - let domains - - if (dom) { - domains = [dom] - } else { - const ret = await this.listDomains() - domains = ret - .filter(x => !x.isExternal) - .map(x => x.name) - .sort((a, b) => a.localeCompare(b)) - } - - const records = new Map() - const bodies = [] - - for (const domain of domains) { - bodies.push( - this.retry(async (bail, attempt) => { - const url = `/domains/${domain}/records` - if (this._debug) { - console.time(`> [debug] #${attempt} GET ${url}`) - } - const res = await this._fetch(url) - if (this._debug) { - console.timeEnd(`> [debug] #${attempt} GET ${url}`) - } - const body = await res.json() - - if (res.status === 404 && body.code === 'not_found') { - return bail(new Error(body.message)) - } else if (res.status !== 200) { - throw new Error(`Failed to get DNS records for domain "${domain}"`) - } - - return body - }) - ) - } - - const domainList = await Promise.all(bodies) - - for (const body of domainList) { - const index = domainList.indexOf(body) - - records.set( - domains[index], - body.records.sort((a, b) => a.slug.localeCompare(b.slug)) - ) - } - - return records - } - - create(domain, data) { - const url = `/domains/${domain}/records` - - return this.retry(async (bail, attempt) => { - if (this._debug) { - console.time(`> [debug] #${attempt} POST ${url}`) - } - const res = await this._fetch(url, { - method: 'POST', - body: data - }) - if (this._debug) { - console.timeEnd(`> [debug] #${attempt} POST ${url}`) - } - - const body = await res.json() - if (res.status === 400) { - return bail( - new Error(body.error ? body.error.message : 'Unknown error') - ) - } else if (res.status === 403) { - const err = new Error(`Not authorized to access the domain "${domain}"`) - err.userError = true - return bail(err) - } else if (res.status === 404) { - let err - - if (body.error.code === 'not_found') { - err = new Error(`The domain "${domain}" was not found`) - err.userError = true - return bail(err) - } - } - - if (res.status !== 200) { - throw new Error(body.error ? body.error.message : 'Unknown error') - } - - return body - }) - } - - delete(domain, recordId) { - const url = `/domains/${domain}/records/${recordId}` - - return this.retry(async (bail, attempt) => { - if (this._debug) { - console.time(`> [debug] #${attempt} DELETE ${url}`) - } - const res = await this._fetch(url, { method: 'DELETE' }) - if (this._debug) { - console.timeEnd(`> [debug] #${attempt} DELETE ${url}`) - } - - const body = await res.json() - if (res.status === 403) { - const err = new Error(`Not authorized to access domain ${domain}`) - err.userError = true - return bail(err) - } else if (res.status === 404) { - let err - - if (body.error.code === 'not_found') { - err = new Error(body.error.message) - err.userError = true - return bail(err) - } - } - - if (res.status !== 200) { - throw new Error(body.error ? body.error.message : 'Unkown error') - } - - return body - }) - } -} diff --git a/lib/domains.js b/lib/domains.js deleted file mode 100644 index 4aff710..0000000 --- a/lib/domains.js +++ /dev/null @@ -1,264 +0,0 @@ -// Native -const { encode: encodeQuery } = require('querystring') - -// Packages -const chalk = require('chalk') - -// Ours -const Now = require('../lib') -const isZeitWorld = require('./is-zeit-world') -const { DNS_VERIFICATION_ERROR } = require('./errors') -const cmd = require('./utils/output/param') - -const domainRegex = /^((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}$/ - -module.exports = class Domains extends Now { - async ls() { - return this.listDomains() - } - - async rm(domain) { - // Remove aliases - for (const aliasId of domain.aliases) { - this.retry(async (bail, attempt) => { - const label = `> [debug] #${attempt} DELETE now/aliases/${aliasId}` - if (this._debug) { - console.time(label) - } - - const res = await this._fetch(`/now/aliases/${aliasId}`, { - method: 'DELETE' - }) - - if (this._debug) { - console.timeEnd(label) - } - - if (res.status === 403) { - return bail(new Error('Unauthorized')) - } - - if (res.status !== 200) { - const body = await res.json() - throw new Error(body.error.message) - } - }) - } - - // Remove certs - for (const cn of domain.certs) { - this.retry(async (bail, attempt) => { - const label = `> [debug] #${attempt} DELETE now/certs/${cn}` - if (this._debug) { - console.time(label) - } - - const res = await this._fetch(`/now/certs/${cn}`, { method: 'DELETE' }) - - if (this._debug) { - console.timeEnd(label) - } - - if (res.status === 403) { - return bail(new Error('Unauthorized')) - } - - if (res.status !== 200) { - const body = await res.json() - throw new Error(body.error.message) - } - }) - } - - // Remove the domain - const name = domain.name - return this.retry(async (bail, attempt) => { - const label = `> [debug] #${attempt} DELETE /domains/${name}` - if (this._debug) { - console.time(label) - } - - const res = await this._fetch(`/domains/${name}`, { method: 'DELETE' }) - - if (this._debug) { - console.timeEnd(label) - } - - if (res.status === 403) { - return bail(new Error('Unauthorized')) - } - - if (res.status === 409) { - const body = await res.json() - return bail(new Error(body.error.message)) - } - - if (res.status !== 200) { - const body = await res.json() - throw new Error(body.error.message) - } - }) - } - - async add(domain, skipVerification, isExternal) { - if (!domainRegex.test(domain)) { - const err = new Error( - `The supplied value ${chalk.bold(`"${domain}"`)} is not a valid domain.` - ) - err.userError = true - throw err - } - - if (skipVerification || isExternal) { - return this.setupDomain(domain, { isExternal }) - } - - let ns - - try { - console.log('> Verifying nameservers…') - const res = await this.getNameservers(domain) - ns = res.nameservers - } catch (err) { - const err2 = new Error( - `Unable to fetch nameservers for ${chalk.underline( - chalk.bold(domain) - )}.` - ) - err2.userError = true - throw err2 - } - - if (isZeitWorld(ns)) { - console.log(`> Verification ${chalk.bold('OK')}!`) - return this.setupDomain(domain) - } - - if (this._debug) { - console.log( - `> [debug] Supplied domain "${domain}" has non-zeit nameservers` - ) - } - - const err3 = new Error(DNS_VERIFICATION_ERROR) - err3.userError = true - throw err3 - } - - async status(name) { - if (!name) { - throw new Error('`domain` is not defined') - } - - const query = encodeQuery({ name }) - - return this.retry(async (bail, attempt) => { - if (this._debug) { - console.time(`> [debug] #${attempt} GET /domains/status?${query}`) - } - - const res = await this._fetch(`/domains/status?${query}`) - const json = await res.json() - - if (this._debug) { - console.timeEnd(`> [debug] #${attempt} GET /domains/status?${query}`) - } - - return json.available - }) - } - - async price(name) { - if (!name) { - throw new Error('`domain` is not defined') - } - - const query = encodeQuery({ name }) - - return this.retry(async (bail, attempt) => { - if (this._debug) { - console.time(`> [debug] #${attempt} GET /domains/price?${query}`) - } - - const res = await this._fetch(`/domains/price?${query}`) - const json = await res.json() - - if (res.status === 400) { - const e = new Error(json.error.message) - e.code = json.error.code - return bail(e) - } - - if (this._debug) { - console.timeEnd(`> [debug] #${attempt} GET /domains/price?${query}`) - } - - return json - }) - } - - async buy({ name, coupon }) { - if (!name) { - throw new Error('`name` is not defined') - } - - const body = JSON.stringify({ name, coupon }) - - return this.retry(async (bail, attempt) => { - if (this._debug) { - console.time(`> [debug] #${attempt} GET /domains/buy`) - } - const res = await this._fetch(`/domains/buy`, { - method: 'POST', - body - }) - const json = await res.json() - - if (this._debug) { - console.timeEnd(`> [debug] #${attempt} GET /domains/buy`) - } - - if ([400, 403, 500, 503].includes(res.status)) { - const e = new Error() - e.code = json.error.code - if (json.error.code === 'source_not_found') { - e.message = `No credit cards found – please run ${cmd('now cc add')}` - } else { - e.message = json.error.message - } - return bail(e) - } - - return json - }) - } - - async coupon(coupon) { - if (!coupon) { - throw new Error('`coupon` is not defined') - } - - const query = encodeQuery({ coupon }) - - return this.retry(async (bail, attempt) => { - if (this._debug) { - console.time(`> [debug] #${attempt} GET /domains/buy?${query}`) - } - - const res = await this._fetch(`/domains/buy?${query}`) - const json = await res.json() - - if (res.status !== 200) { - const e = new Error(json.error.message) - e.code = json.error.code - return bail(e) - } - - if (this._debug) { - console.timeEnd(`> [debug] #${attempt} GET /domains/buy?${query}`) - } - - return json - }) - } -} diff --git a/lib/error.js b/lib/error.js deleted file mode 100644 index c94c589..0000000 --- a/lib/error.js +++ /dev/null @@ -1,85 +0,0 @@ -// Packages -const ms = require('ms') -const chalk = require('chalk') - -const error = require('./utils/output/error') -const info = require('./utils/output/info') - -function handleError(err, { debug = false } = {}) { - // Coerce Strings to Error instances - if (typeof err === 'string') { - err = new Error(err) - } - - if (debug) { - console.log(`> [debug] handling error: ${err.stack}`) - } - - if (err.status === 403) { - error( - 'Authentication error. Run `now -L` or `now --login` to log-in again.' - ) - } else if (err.status === 429) { - if (err.retryAfter === 'never') { - error(err.message) - } else if (err.retryAfter === null) { - error('Rate limit exceeded error. Please try later.') - } else { - error( - 'Rate limit exceeded error. Try again in ' + - ms(err.retryAfter * 1000, { long: true }) + - ', or upgrade your account by running ' + - `${chalk.gray('`')}${chalk.cyan('now upgrade')}${chalk.gray('`')}` - ) - } - } else if (err.userError) { - error(err.message) - } else if (err.status === 500) { - error('Unexpected server error. Please retry.') - } else if (err.code === 'USER_ABORT') { - info('Aborted') - } else { - error(`Unexpected error. Please try again later. (${err.message})`) - } -} - -async function responseError(res) { - let message - let userError - - if (res.status >= 400 && res.status < 500) { - let body - - try { - body = await res.json() - } catch (err) { - body = {} - } - - // Some APIs wrongly return `err` instead of `error` - message = (body.error || body.err || {}).message - userError = true - } else { - userError = false - } - - const err = new Error(message || 'Response error') - err.status = res.status - err.userError = userError - - if (res.status === 429) { - const retryAfter = res.headers.get('Retry-After') - - if (retryAfter) { - err.retryAfter = parseInt(retryAfter, 10) - } - } - - return err -} - -module.exports = { - handleError, - responseError, - error -} diff --git a/lib/errors.js b/lib/errors.js deleted file mode 100644 index 7d9af29..0000000 --- a/lib/errors.js +++ /dev/null @@ -1,30 +0,0 @@ -// Packages -const chalk = require('chalk') - -const DNS_VERIFICATION_ERROR = `Please make sure that your nameservers point to ${chalk.underline( - 'zeit.world' -)}. -> Examples: (full list at ${chalk.underline('https://zeit.world')}) -> ${chalk.gray('-')} ${chalk.underline('california.zeit.world')} ${chalk.dim( - '173.255.215.107' -)} -> ${chalk.gray('-')} ${chalk.underline('newark.zeit.world')} ${chalk.dim( - '173.255.231.87' -)} -> ${chalk.gray('-')} ${chalk.underline('london.zeit.world')} ${chalk.dim( - '178.62.47.76' -)} -> ${chalk.gray('-')} ${chalk.underline('singapore.zeit.world')} ${chalk.dim( - '119.81.97.170' -)}` - -const DOMAIN_VERIFICATION_ERROR = - DNS_VERIFICATION_ERROR + - `\n> Alternatively, ensure it resolves to ${chalk.underline( - 'alias.zeit.co' - )} via ${chalk.dim('CNAME')} / ${chalk.dim('ALIAS')}.` - -module.exports = { - DNS_VERIFICATION_ERROR, - DOMAIN_VERIFICATION_ERROR -} diff --git a/lib/get-files.js b/lib/get-files.js deleted file mode 100644 index 0147889..0000000 --- a/lib/get-files.js +++ /dev/null @@ -1,385 +0,0 @@ -// Native -const { resolve } = require('path') - -// Packages -const flatten = require('arr-flatten') -const unique = require('array-unique') -const ignore = require('ignore') -const _glob = require('glob') -const { stat, readdir, readFile } = require('fs-extra') - -// Ours -const IGNORED = require('./ignored') - -const glob = async function(pattern, options) { - return new Promise((resolve, reject) => { - _glob(pattern, options, (error, files) => { - if (error) { - reject(error) - } else { - resolve(files) - } - }) - }) -} - -/** - * Remove leading `./` from the beginning of ignores - * because our parser doesn't like them :| - */ - -const clearRelative = function(str) { - return str.replace(/(\n|^)\.\//g, '$1') -} - -/** - * Returns the contents of a file if it exists. - * - * @return {String} results or `''` - */ - -const maybeRead = async function(path, default_ = '') { - try { - return await readFile(path, 'utf8') - } catch (err) { - return default_ - } -} - -/** - * Transform relative paths into absolutes, - * and maintains absolutes as such. - * - * @param {String} maybe relative path - * @param {String} parent full path - */ - -const asAbsolute = function(path, parent) { - if (path[0] === '/') { - return path - } - - return resolve(parent, path) -} - -/** - * Returns a list of files in the given - * directory that are subject to be - * synchronized for static deployments. - * - * @param {String} full path to directory - * @param {Object} options: - * - `limit` {Number|null} byte limit - * - `debug` {Boolean} warn upon ignore - * @return {Array} comprehensive list of paths to sync - */ - -async function staticFiles( - path, - nowConfig = {}, - { limit = null, hasNowJson = false, debug = false } = {} -) { - const whitelist = nowConfig.files - - // The package.json `files` whitelist still - // honors ignores: https://docs.npmjs.com/files/package.json#files - const search_ = whitelist || ['.'] - // Convert all filenames into absolute paths - const search = Array.prototype.concat.apply( - [], - await Promise.all( - search_.map(file => glob(file, { cwd: path, absolute: true, dot: true })) - ) - ) - - // Compile list of ignored patterns and files - const gitIgnore = await maybeRead(resolve(path, '.gitignore')) - - const filter = ignore() - .add(IGNORED + '\n' + clearRelative(gitIgnore)) - .createFilter() - - const prefixLength = path.length + 1 - - // The package.json `files` whitelist still - // honors npmignores: https://docs.npmjs.com/files/package.json#files - // but we don't ignore if the user is explicitly listing files - // under the now namespace, or using files in combination with gitignore - const accepts = file => { - const relativePath = file.substr(prefixLength) - - if (relativePath === '') { - return true - } - - const accepted = filter(relativePath) - if (!accepted && debug) { - console.log('> [debug] ignoring "%s"', file) - } - return accepted - } - - // Locate files - if (debug) { - console.time(`> [debug] locating files ${path}`) - } - - const files = await explode(search, { - accepts, - limit, - debug - }) - - if (debug) { - console.timeEnd(`> [debug] locating files ${path}`) - } - - if (hasNowJson) { - files.push(asAbsolute('now.json', path)) - } - - // Get files - return unique(files) -} - -/** - * Returns a list of files in the given - * directory that are subject to be - * synchronized for npm. - * - * @param {String} full path to directory - * @param {String} contents of `package.json` to avoid lookup - * @param {Object} options: - * - `limit` {Number|null} byte limit - * - `debug` {Boolean} warn upon ignore - * @return {Array} comprehensive list of paths to sync - */ - -async function npm( - path, - pkg = {}, - nowConfig = {}, - { limit = null, hasNowJson = false, debug = false } = {} -) { - const whitelist = nowConfig.files || pkg.files || (pkg.now && pkg.now.files) - - // The package.json `files` whitelist still - // honors ignores: https://docs.npmjs.com/files/package.json#files - const search_ = whitelist || ['.'] - // Convert all filenames into absolute paths - const search = Array.prototype.concat.apply( - [], - await Promise.all( - search_.map(file => glob(file, { cwd: path, absolute: true, dot: true })) - ) - ) - - // Compile list of ignored patterns and files - const npmIgnore = await maybeRead(resolve(path, '.npmignore'), null) - const gitIgnore = - npmIgnore === null ? await maybeRead(resolve(path, '.gitignore')) : null - - const filter = ignore() - .add( - IGNORED + '\n' + clearRelative(npmIgnore === null ? gitIgnore : npmIgnore) - ) - .createFilter() - - const prefixLength = path.length + 1 - - // The package.json `files` whitelist still - // honors npmignores: https://docs.npmjs.com/files/package.json#files - // but we don't ignore if the user is explicitly listing files - // under the now namespace, or using files in combination with gitignore - const overrideIgnores = - (pkg.now && pkg.now.files) || - nowConfig.files || - (gitIgnore !== null && pkg.files) - const accepts = overrideIgnores - ? () => true - : file => { - const relativePath = file.substr(prefixLength) - - if (relativePath === '') { - return true - } - - const accepted = filter(relativePath) - if (!accepted && debug) { - console.log('> [debug] ignoring "%s"', file) - } - return accepted - } - - // Locate files - if (debug) { - console.time(`> [debug] locating files ${path}`) - } - - const files = await explode(search, { - accepts, - limit, - debug - }) - - if (debug) { - console.timeEnd(`> [debug] locating files ${path}`) - } - - // Always include manifest as npm does not allow ignoring it - // source: https://docs.npmjs.com/files/package.json#files - files.push(asAbsolute('package.json', path)) - - if (hasNowJson) { - files.push(asAbsolute('now.json', path)) - } - - // Get files - return unique(files) -} - -/** - * Returns a list of files in the given - * directory that are subject to be - * sent to docker as build context. - * - * @param {String} full path to directory - * @param {String} contents of `Dockerfile` - * @param {Object} options: - * - `limit` {Number|null} byte limit - * - `debug` {Boolean} warn upon ignore - * @return {Array} comprehensive list of paths to sync - */ - -async function docker( - path, - nowConfig = {}, - { limit = null, hasNowJson = false, debug = false } = {} -) { - const whitelist = nowConfig.files - - // Base search path - // the now.json `files` whitelist still - // honors ignores: https://docs.npmjs.com/files/package.json#files - const search_ = whitelist || ['.'] - - // Convert all filenames into absolute paths - const search = search_.map(file => asAbsolute(file, path)) - - // Compile list of ignored patterns and files - const dockerIgnore = await maybeRead(resolve(path, '.dockerignore'), null) - - const filter = ignore() - .add( - IGNORED + - '\n' + - clearRelative( - dockerIgnore === null - ? await maybeRead(resolve(path, '.gitignore')) - : dockerIgnore - ) - ) - .createFilter() - - const prefixLength = path.length + 1 - const accepts = function(file) { - const relativePath = file.substr(prefixLength) - - if (relativePath === '') { - return true - } - - const accepted = filter(relativePath) - if (!accepted && debug) { - console.log('> [debug] ignoring "%s"', file) - } - return accepted - } - - // Locate files - if (debug) { - console.time(`> [debug] locating files ${path}`) - } - - const files = await explode(search, { accepts, limit, debug }) - - if (debug) { - console.timeEnd(`> [debug] locating files ${path}`) - } - - // Always include manifest as npm does not allow ignoring it - // source: https://docs.npmjs.com/files/package.json#files - files.push(asAbsolute('Dockerfile', path)) - - if (hasNowJson) { - files.push(asAbsolute('now.json', path)) - } - - // Get files - return unique(files) -} - -/** - * Explodes directories into a full list of files. - * Eg: - * in: ['/a.js', '/b'] - * out: ['/a.js', '/b/c.js', '/b/d.js'] - * - * @param {Array} of {String}s representing paths - * @param {Array} of ignored {String}s. - * @param {Object} options: - * - `limit` {Number|null} byte limit - * - `debug` {Boolean} warn upon ignore - * @return {Array} of {String}s of full paths - */ - -async function explode(paths, { accepts, debug }) { - const list = async file => { - let path = file - let s - - if (!accepts(file)) { - return null - } - - try { - s = await stat(path) - } catch (e) { - // In case the file comes from `files` - // and it wasn't specified with `.js` by the user - path = file + '.js' - - try { - s = await stat(path) - } catch (e2) { - if (debug) { - console.log('> [debug] ignoring invalid file "%s"', file) - } - return null - } - } - - if (s.isDirectory()) { - const all = await readdir(file) - /* eslint-disable no-use-before-define */ - return many(all.map(subdir => asAbsolute(subdir, file))) - /* eslint-enable no-use-before-define */ - } else if (!s.isFile()) { - if (debug) { - console.log('> [debug] ignoring special file "%s"', file) - } - return null - } - - return path - } - - const many = all => Promise.all(all.map(file => list(file))) - return flatten(await many(paths)).filter(v => v !== null) -} - -module.exports = { - npm, - docker, - staticFiles -} diff --git a/lib/git.js b/lib/git.js deleted file mode 100644 index 2624569..0000000 --- a/lib/git.js +++ /dev/null @@ -1,221 +0,0 @@ -// Native -const path = require('path') -const url = require('url') -const childProcess = require('child_process') - -// Packages -const fs = require('fs-extra') -const download = require('download') -const tmp = require('tmp-promise') -const isURL = require('is-url') - -const cloneRepo = (parts, tmpDir, { ssh }) => - new Promise((resolve, reject) => { - let host - - switch (parts.type) { - case 'GitLab': - host = `gitlab.com` - break - case 'Bitbucket': - host = `bitbucket.org` - break - default: - host = `github.com` - } - - const url = ssh - ? `git@${host}:${parts.main}` - : `https://${host}/${parts.main}` - - const ref = parts.ref || (parts.type === 'Bitbucket' ? 'default' : 'master') - const cmd = `git clone ${url} --single-branch ${ref}` - - childProcess.exec(cmd, { cwd: tmpDir.path }, (err, stdout) => { - if (err) { - reject(err) - } - - resolve(stdout) - }) - }) - -const renameRepoDir = async (pathParts, tmpDir) => { - const tmpContents = await fs.readdir(tmpDir.path) - - const oldTemp = path.join(tmpDir.path, tmpContents[0]) - const newTemp = path.join(tmpDir.path, pathParts.main.replace('/', '-')) - - await fs.rename(oldTemp, newTemp) - tmpDir.path = newTemp - - return tmpDir -} - -const capitalizePlatform = name => { - const names = { - github: 'GitHub', - gitlab: 'GitLab', - bitbucket: 'Bitbucket' - } - - return names[name] -} - -const splittedURL = fullURL => { - const parsedURL = url.parse(fullURL) - const pathParts = parsedURL.path.split('/') - - pathParts.shift() - - // Set path to repo... - const main = pathParts[0] + '/' + pathParts[1] - - // ...and then remove it from the parts - pathParts.splice(0, 2) - - // Assign Git reference - let ref = pathParts.length >= 2 ? pathParts[1] : '' - - // Firstly be sure that we haven know the ref type - if (pathParts[0]) { - // Then shorten the SHA of the commit - if (pathParts[0] === 'commit' || pathParts[0] === 'commits') { - ref = ref.substring(0, 7) - } - } - - // We're deploying master by default, - // so there's no need to indicate it explicitly - if (ref === 'master') { - ref = '' - } - - return { - main, - ref, - type: capitalizePlatform(parsedURL.host.split('.')[0]) - } -} - -const gitPathParts = main => { - let ref = '' - - if (isURL(main)) { - return splittedURL(main) - } - - if (main.split('/')[1].includes('#')) { - const parts = main.split('#') - - ref = parts[1] - main = parts[0] - } - - return { - main, - ref, - type: capitalizePlatform('github') - } -} - -const downloadRepo = async repoPath => { - const pathParts = gitPathParts(repoPath) - - const tmpDir = await tmp.dir({ - // We'll remove it manually once deployment is done - keep: true, - // Recursively remove directory when calling respective method - unsafeCleanup: true - }) - - let gitInstalled = true - - try { - await cloneRepo(pathParts, tmpDir) - } catch (err) { - try { - await cloneRepo(pathParts, tmpDir, { ssh: true }) - } catch (err) { - gitInstalled = false - } - } - - if (gitInstalled) { - const renaming = await renameRepoDir(pathParts, tmpDir) - return renaming - } - - let url - - switch (pathParts.type) { - case 'GitLab': { - const ref = pathParts.ref ? `?ref=${pathParts.ref}` : '' - url = `https://gitlab.com/${pathParts.main}/repository/archive.tar` + ref - break - } - case 'Bitbucket': - url = `https://bitbucket.org/${pathParts.main}/get/${pathParts.ref || - 'default'}.zip` - break - default: - url = `https://api.github.com/repos/${pathParts.main}/tarball/${pathParts.ref}` - } - - try { - await download(url, tmpDir.path, { - extract: true - }) - } catch (err) { - tmpDir.cleanup() - return false - } - - const renaming = await renameRepoDir(pathParts, tmpDir) - return renaming -} - -const isRepoPath = path => { - if (!path) { - return false - } - - const allowedHosts = ['github.com', 'gitlab.com', 'bitbucket.org'] - - if (isURL(path)) { - const urlParts = url.parse(path) - const slashSplitted = urlParts.path.split('/').filter(n => n) - const notBare = slashSplitted.length >= 2 - - if (allowedHosts.includes(urlParts.host) && notBare) { - return true - } - - const err = new Error(`Host "${urlParts.host}" is unsupported.`) - err.code = 'INVALID_URL' - err.userError = true - throw err - } - - return /[^\s\\]\/[^\s\\]/g.test(path) -} - -const fromGit = async (path, debug) => { - let tmpDir = false - - try { - tmpDir = await downloadRepo(path) - } catch (err) { - if (debug) { - console.log(`Could not download "${path}" repo from GitHub`) - } - } - - return tmpDir -} - -module.exports = { - gitPathParts, - isRepoPath, - fromGit -} diff --git a/lib/hash.js b/lib/hash.js deleted file mode 100644 index b5a7d63..0000000 --- a/lib/hash.js +++ /dev/null @@ -1,44 +0,0 @@ -// Native -const { createHash } = require('crypto') - -// Packages -const { readFile } = require('fs-extra') - -/** - * Computes hashes for the contents of each file given. - * - * @param {Array} of {String} full paths - * @return {Map} - */ - -async function hashes(files) { - const map = new Map() - - await Promise.all( - files.map(async name => { - const data = await readFile(name) - - const h = hash(data) - const entry = map.get(h) - if (entry) { - entry.names.push(name) - } else { - map.set(hash(data), { names: [name], data }) - } - }) - ) - return map -} - -/** - * Computes a hash for the given buf. - * - * @param {Buffer} file data - * @return {String} hex digest - */ - -function hash(buf) { - return createHash('sha1').update(buf).digest('hex') -} - -module.exports = hashes diff --git a/lib/ignored.js b/lib/ignored.js deleted file mode 100644 index e71a28f..0000000 --- a/lib/ignored.js +++ /dev/null @@ -1,17 +0,0 @@ -// Base `.gitignore` to which we add entries -// supplied by the user -module.exports = `.hg -.git -.gitmodules -.svn -.npmignore -.dockerignore -.gitignore -.*.swp -.DS_Store -.wafpicke-* -.lock-wscript -npm-debug.log -config.gypi -node_modules -CVS` diff --git a/lib/indent.js b/lib/indent.js deleted file mode 100644 index f934288..0000000 --- a/lib/indent.js +++ /dev/null @@ -1,5 +0,0 @@ -function indent(text, n) { - return text.split('\n').map(l => ' '.repeat(n) + l).join('\n') -} - -module.exports = indent diff --git a/lib/index.js b/lib/index.js deleted file mode 100644 index c337426..0000000 --- a/lib/index.js +++ /dev/null @@ -1,1029 +0,0 @@ -// Native -const { homedir } = require('os') -const { resolve: resolvePath } = require('path') -const EventEmitter = require('events') -const qs = require('querystring') -const { parse: parseUrl } = require('url') - -// Packages -const fetch = require('node-fetch') -const bytes = require('bytes') -const chalk = require('chalk') -const resumer = require('resumer') -const retry = require('async-retry') -const splitArray = require('split-array') -const { parse: parseIni } = require('ini') -const { readFile, stat, lstat } = require('fs-extra') -const ms = require('ms') - -// Utilities -const { - staticFiles: getFiles, - npm: getNpmFiles, - docker: getDockerFiles -} = require('./get-files') -const ua = require('./ua') -const hash = require('./hash') -const Agent = require('./agent') -const toHost = require('./to-host') -const { responseError } = require('./error') - -// How many concurrent HTTP/2 stream uploads -const MAX_CONCURRENT = 10 - -// Check if running windows -const IS_WIN = process.platform.startsWith('win') -const SEP = IS_WIN ? '\\' : '/' - -module.exports = class Now extends EventEmitter { - constructor({ apiUrl, token, currentTeam, forceNew = false, debug = false }) { - super() - this._token = token - this._debug = debug - this._forceNew = forceNew - this._agent = new Agent(apiUrl, { debug }) - this._onRetry = this._onRetry.bind(this) - this.currentTeam = currentTeam - } - - async create( - path, - { - wantsPublic, - quiet = false, - env = {}, - followSymlinks = true, - forceNew = false, - forceSync = false, - forwardNpm = false, - - // From readMetaData - name, - description, - type = 'npm', - pkg = {}, - nowConfig = {}, - hasNowJson = false, - sessionAffinity = 'ip' - } - ) { - this._path = path - - let files - let engines - - if (this._debug) { - console.time('> [debug] Getting files') - } - - const opts = { debug: this._debug, hasNowJson } - if (type === 'npm') { - files = await getNpmFiles(path, pkg, nowConfig, opts) - - // A `start` or `now-start` npm script, or a `server.js` file - // in the root directory of the deployment are required - if (!hasNpmStart(pkg) && !hasFile(path, files, 'server.js')) { - const err = new Error( - 'Missing `start` (or `now-start`) script in `package.json`. ' + - 'See: https://docs.npmjs.com/cli/start.' - ) - err.userError = true - throw err - } - - engines = nowConfig.engines || pkg.engines - forwardNpm = forwardNpm || nowConfig.forwardNpm - } else if (type === 'static') { - files = await getFiles(path, nowConfig, opts) - } else if (type === 'docker') { - files = await getDockerFiles(path, nowConfig, opts) - } - - if (this._debug) { - console.timeEnd('> [debug] Getting files') - } - - // Read `registry.npmjs.org` authToken from .npmrc - let authToken - if (type === 'npm' && forwardNpm) { - authToken = - (await readAuthToken(path)) || (await readAuthToken(homedir())) - } - - if (this._debug) { - console.time('> [debug] Computing hashes') - } - - const pkgDetails = Object.assign({ name }, pkg) - const hashes = await hash(files, pkgDetails) - - if (this._debug) { - console.timeEnd('> [debug] Computing hashes') - } - - this._files = hashes - - const deployment = await this.retry(async bail => { - if (this._debug) { - console.time('> [debug] /now/create') - } - - // Flatten the array to contain files to sync where each nested input - // array has a group of files with the same sha but different path - const files = await Promise.all( - Array.prototype.concat.apply( - [], - await Promise.all( - Array.from(this._files).map(async ([sha, { data, names }]) => { - const statFn = followSymlinks ? stat : lstat - - return names.map(async name => { - const getMode = async () => { - const st = await statFn(name) - return st.mode - } - - const mode = await getMode() - - return { - sha, - size: data.length, - file: toRelative(name, this._path), - mode - } - }) - }) - ) - ) - ) - - const res = await this._fetch('/now/create', { - method: 'POST', - body: { - env, - public: wantsPublic || nowConfig.public, - forceNew, - forceSync, - name, - description, - deploymentType: type, - registryAuthToken: authToken, - files, - engines, - sessionAffinity - } - }) - - if (this._debug) { - console.timeEnd('> [debug] /now/create') - } - - // No retry on 4xx - let body - try { - body = await res.json() - } catch (err) { - throw new Error('Unexpected response') - } - - if (res.status === 429) { - let msg = `You reached your 20 deployments limit in the OSS plan.\n` - msg += `${chalk.gray('>')} Please run ${chalk.gray('`')}${chalk.cyan( - 'now upgrade' - )}${chalk.gray('`')} to proceed` - const err = new Error(msg) - err.status = res.status - err.retryAfter = 'never' - return bail(err) - } else if (res.status >= 400 && res.status < 500) { - const err = new Error(body.error.message) - err.userError = true - return bail(err) - } else if (res.status !== 200) { - throw new Error(body.error.message) - } - - return body - }) - - // We report about files whose sizes are too big - let missingVersion = false - if (deployment.warnings) { - let sizeExceeded = 0 - deployment.warnings.forEach(warning => { - if (warning.reason === 'size_limit_exceeded') { - const { sha, limit } = warning - const n = hashes.get(sha).names.pop() - console.error( - '> \u001B[31mWarning!\u001B[39m Skipping file %s (size exceeded %s)', - n, - bytes(limit) - ) - hashes.get(sha).names.unshift(n) // Move name (hack, if duplicate matches we report them in order) - sizeExceeded++ - } else if (warning.reason === 'node_version_not_found') { - const { wanted, used } = warning - console.error( - '> \u001B[31mWarning!\u001B[39m Requested node version %s is not available', - wanted, - used - ) - missingVersion = true - } - }) - - if (sizeExceeded) { - console.error( - `> \u001B[31mWarning!\u001B[39m ${sizeExceeded} of the files ` + - 'exceeded the limit for your plan.\n' + - `> Please run ${chalk.gray('`')}${chalk.cyan( - 'now upgrade' - )}${chalk.gray('`')} to upgrade.` - ) - } - } - - if (!quiet && type === 'npm' && deployment.nodeVersion) { - if (engines && engines.node) { - if (missingVersion) { - console.log( - `> Using Node.js ${chalk.bold(deployment.nodeVersion)} (default)` - ) - } else { - console.log( - `> Using Node.js ${chalk.bold( - deployment.nodeVersion - )} (requested: ${chalk.dim(`\`${engines.node}\``)})` - ) - } - } else { - console.log( - `> Using Node.js ${chalk.bold(deployment.nodeVersion)} (default)` - ) - } - } - - this._id = deployment.deploymentId - this._host = deployment.url - this._missing = deployment.missing || [] - this._fileCount = files.length - - return this._url - } - - upload() { - const parts = splitArray(this._missing, MAX_CONCURRENT) - - if (this._debug) { - console.log( - '> [debug] Will upload ' + - `${this._missing.length} files in ${parts.length} ` + - `steps of ${MAX_CONCURRENT} uploads.` - ) - } - - const uploadChunk = () => { - Promise.all( - parts.shift().map(sha => - retry( - async (bail, attempt) => { - const file = this._files.get(sha) - const { data, names } = file - - if (this._debug) { - console.time(`> [debug] /sync #${attempt} ${names.join(' ')}`) - } - - const stream = resumer().queue(data).end() - const res = await this._fetch('/now/sync', { - method: 'POST', - headers: { - 'Content-Type': 'application/octet-stream', - 'Content-Length': data.length, - 'x-now-deployment-id': this._id, - 'x-now-sha': sha, - 'x-now-file': names - .map(name => { - return toRelative(encodeURIComponent(name), this._path) - }) - .join(','), - 'x-now-size': data.length - }, - body: stream - }) - - if (this._debug) { - console.timeEnd( - `> [debug] /sync #${attempt} ${names.join(' ')}` - ) - } - - // No retry on 4xx - if ( - res.status !== 200 && - (res.status >= 400 || res.status < 500) - ) { - if (this._debug) { - console.log( - '> [debug] bailing on creating due to %s', - res.status - ) - } - - return bail(await responseError(res)) - } - - this.emit('upload', file) - }, - { retries: 3, randomize: true, onRetry: this._onRetry } - ) - ) - ) - .then(() => (parts.length ? uploadChunk() : this.emit('complete'))) - .catch(err => this.emit('error', err)) - } - - uploadChunk() - } - - async listSecrets() { - return this.retry(async (bail, attempt) => { - if (this._debug) { - console.time(`> [debug] #${attempt} GET /secrets`) - } - - const res = await this._fetch('/now/secrets') - - if (this._debug) { - console.timeEnd(`> [debug] #${attempt} GET /secrets`) - } - - const body = await res.json() - return body.secrets - }) - } - - async list(app) { - const query = app ? `?app=${encodeURIComponent(app)}` : '' - - const { deployments } = await this.retry( - async bail => { - if (this._debug) { - console.time('> [debug] /list') - } - - const res = await this._fetch('/now/list' + query) - - if (this._debug) { - console.timeEnd('> [debug] /list') - } - - // No retry on 4xx - if (res.status >= 400 && res.status < 500) { - if (this._debug) { - console.log('> [debug] bailing on listing due to %s', res.status) - } - return bail(await responseError(res)) - } - - if (res.status !== 200) { - throw new Error('Fetching deployment url failed') - } - - return res.json() - }, - { retries: 3, minTimeout: 2500, onRetry: this._onRetry } - ) - - return deployments - } - - async listInstances(deploymentId) { - const { instances } = await this.retry( - async bail => { - if (this._debug) { - console.time(`> [debug] /deployments/${deploymentId}/instances`) - } - - const res = await this._fetch( - `/now/deployments/${deploymentId}/instances` - ) - - if (this._debug) { - console.timeEnd(`> [debug] /deployments/${deploymentId}/instances`) - } - - // No retry on 4xx - if (res.status >= 400 && res.status < 500) { - if (this._debug) { - console.log('> [debug] bailing on listing due to %s', res.status) - } - return bail(await responseError(res)) - } - - if (res.status !== 200) { - throw new Error('Fetching instances list failed') - } - - return res.json() - }, - { retries: 3, minTimeout: 2500, onRetry: this._onRetry } - ) - - return instances - } - - async findDeployment(deployment) { - const list = await this.list() - - let key - let val - - if (/\./.test(deployment)) { - val = toHost(deployment) - key = 'url' - } else { - val = deployment - key = 'uid' - } - - const depl = list.find(d => { - if (d[key] === val) { - if (this._debug) { - console.log(`> [debug] matched deployment ${d.uid} by ${key} ${val}`) - } - - return true - } - - // Match prefix - if (`${val}.now.sh` === d.url) { - if (this._debug) { - console.log(`> [debug] matched deployment ${d.uid} by url ${d.url}`) - } - - return true - } - - return false - }) - - return depl - } - - async logs( - deploymentIdOrURL, - { instanceId, types, limit, query, since, until } = {} - ) { - const q = qs.stringify({ - instanceId, - types: types.join(','), - limit, - q: query, - since, - until - }) - - const { logs } = await this.retry( - async bail => { - if (this._debug) { - console.time('> [debug] /logs') - } - - const url = `/now/deployments/${encodeURIComponent( - deploymentIdOrURL - )}/logs?${q}` - const res = await this._fetch(url) - - if (this._debug) { - console.timeEnd('> [debug] /logs') - } - - // No retry on 4xx - if (res.status >= 400 && res.status < 500) { - if (this._debug) { - console.log( - '> [debug] bailing on printing logs due to %s', - res.status - ) - } - - return bail(await responseError(res)) - } - - if (res.status !== 200) { - throw new Error('Fetching deployment logs failed') - } - - return res.json() - }, - { - retries: 3, - minTimeout: 2500, - onRetry: this._onRetry - } - ) - - return logs - } - - async listAliases(deploymentId) { - return this.retry(async bail => { - const res = await this._fetch( - deploymentId - ? `/now/deployments/${deploymentId}/aliases` - : '/now/aliases' - ) - - if (res.status >= 400 && res.status < 500) { - if (this._debug) { - console.log('> [debug] bailing on get domain due to %s', res.status) - } - return bail(await responseError(res)) - } - - if (res.status !== 200) { - throw new Error('API error getting aliases') - } - - const body = await res.json() - return body.aliases - }) - } - - async last(app) { - const deployments = await this.list(app) - - const last = deployments - .sort((a, b) => { - return b.created - a.created - }) - .shift() - - if (!last) { - const e = Error(`No deployments found for "${app}"`) - e.userError = true - throw e - } - - return last - } - - async listDomains() { - return this.retry(async (bail, attempt) => { - if (this._debug) { - console.time(`> [debug] #${attempt} GET /domains`) - } - - const res = await this._fetch('/domains') - - if (this._debug) { - console.timeEnd(`> [debug] #${attempt} GET /domains`) - } - - if (res.status >= 400 && res.status < 500) { - if (this._debug) { - console.log('> [debug] bailing on get domain due to %s', res.status) - } - return bail(await responseError(res)) - } - - if (res.status !== 200) { - throw new Error('API error getting domains') - } - - const body = await res.json() - return body.domains - }) - } - - async getDomain(domain) { - return this.retry(async (bail, attempt) => { - if (this._debug) { - console.time(`> [debug] #${attempt} GET /domains/${domain}`) - } - - const res = await this._fetch(`/domains/${domain}`) - - if (res.status >= 400 && res.status < 500) { - if (this._debug) { - console.log('> [debug] bailing on get domain due to %s', res.status) - } - return bail(await responseError(res)) - } - - if (res.status !== 200) { - throw new Error('API error getting domain name') - } - - if (this._debug) { - console.timeEnd(`> [debug] #${attempt} GET /domains/${domain}`) - } - - return res.json() - }) - } - - getNameservers(domain) { - return new Promise((resolve, reject) => { - let fallback = false - - this.retry(async (bail, attempt) => { - if (this._debug) { - console.time( - `> [debug] #${attempt} GET /whois-ns${fallback ? '-fallback' : ''}` - ) - } - - const res = await this._fetch( - `/whois-ns${fallback ? '-fallback' : ''}?domain=${encodeURIComponent( - domain - )}` - ) - - if (this._debug) { - console.timeEnd( - `> [debug] #${attempt} GET /whois-ns${fallback ? '-fallback' : ''}` - ) - } - - const body = await res.json() - - if (res.status === 200) { - if ( - (!body.nameservers || body.nameservers.length === 0) && - !fallback - ) { - // If the nameservers are `null` it's likely - // that our whois service failed to parse it - fallback = true - throw new Error('Invalid whois response') - } - - return body - } - - if (attempt > 1) { - fallback = true - } - - throw new Error(`Whois error (${res.status}): ${body.error.message}`) - }) - .then(body => { - body.nameservers = body.nameservers.filter(ns => { - // Temporary hack: - // sometimes we get a response that looks like: - // ['ns', 'ns', '', ''] - // so we filter the empty ones - return ns.length - }) - resolve(body) - }) - .catch(err => { - reject(err) - }) - }) - } - - // _ensures_ the domain is setup (idempotent) - setupDomain(name, { isExternal } = {}) { - return this.retry(async (bail, attempt) => { - if (this._debug) { - console.time(`> [debug] #${attempt} POST /domains`) - } - - const res = await this._fetch('/domains', { - method: 'POST', - body: { name, isExternal: Boolean(isExternal) } - }) - - if (this._debug) { - console.timeEnd(`> [debug] #${attempt} POST /domains`) - } - - const body = await res.json() - - if (res.status === 403) { - const code = body.error.code - let err - - if (code === 'custom_domain_needs_upgrade') { - err = new Error( - `Custom domains are only enabled for premium accounts. Please upgrade at ${chalk.underline( - 'https://zeit.co/account' - )}.` - ) - } else { - err = new Error(`Not authorized to access domain ${name}`) - } - - err.userError = true - return bail(err) - } else if (res.status === 409) { - // Domain already exists - if (this._debug) { - console.log('> [debug] Domain already exists (noop)') - } - - return { uid: body.error.uid, code: body.error.code } - } else if ( - res.status === 401 && - body.error && - body.error.code === 'verification_failed' - ) { - throw new Error(body.error.message) - } else if (res.status !== 200) { - throw new Error(body.error.message) - } - - return body - }) - } - - createCert(domain, { renew } = {}) { - return this.retry( - async (bail, attempt) => { - if (this._debug) { - console.time(`> [debug] /now/certs #${attempt}`) - } - - const res = await this._fetch('/now/certs', { - method: 'POST', - body: { - domains: [domain], - renew - } - }) - - if (res.status === 304) { - console.log('> Certificate already issued.') - return - } - - const body = await res.json() - - if (this._debug) { - console.timeEnd(`> [debug] /now/certs #${attempt}`) - } - - if (body.error) { - const { code } = body.error - - if (code === 'verification_failed') { - const err = new Error( - 'The certificate issuer failed to verify ownership of the domain. ' + - 'This likely has to do with DNS propagation and caching issues. Please retry later!' - ) - err.userError = true - // Retry - throw err - } else if (code === 'rate_limited') { - const err = new Error(body.error.message) - err.userError = true - // Dont retry - return bail(err) - } - - throw new Error(body.error.message) - } - - if (res.status !== 200 && res.status !== 304) { - throw new Error('Unhandled error') - } - return body - }, - { retries: 3, minTimeout: 30000, maxTimeout: 90000 } - ) - } - - deleteCert(domain) { - return this.retry( - async (bail, attempt) => { - if (this._debug) { - console.time(`> [debug] /now/certs #${attempt}`) - } - - const res = await this._fetch(`/now/certs/${domain}`, { - method: 'DELETE' - }) - - if (res.status !== 200) { - const err = new Error(res.body.error.message) - err.userError = false - - if (res.status === 400 || res.status === 404) { - return bail(err) - } - - throw err - } - }, - { retries: 3 } - ) - } - - async remove(deploymentId, { hard }) { - const data = { deploymentId, hard } - - await this.retry(async bail => { - if (this._debug) { - console.time('> [debug] /remove') - } - - const res = await this._fetch('/now/remove', { - method: 'DELETE', - body: data - }) - - if (this._debug) { - console.timeEnd('> [debug] /remove') - } - - // No retry on 4xx - if (res.status >= 400 && res.status < 500) { - if (this._debug) { - console.log('> [debug] bailing on removal due to %s', res.status) - } - return bail(await responseError(res)) - } - - if (res.status !== 200) { - throw new Error('Removing deployment failed') - } - }) - - return true - } - - retry(fn, { retries = 3, maxTimeout = Infinity } = {}) { - return retry(fn, { - retries, - maxTimeout, - onRetry: this._onRetry - }) - } - - _onRetry(err) { - if (this._debug) { - console.log(`> [debug] Retrying: ${err}\n${err.stack}`) - } - } - - close() { - this._agent.close() - } - - get id() { - return this._id - } - - get url() { - return `https://${this._host}` - } - - get fileCount() { - return this._fileCount - } - - get host() { - return this._host - } - - get syncAmount() { - if (!this._syncAmount) { - this._syncAmount = this._missing - .map(sha => this._files.get(sha).data.length) - .reduce((a, b) => a + b, 0) - } - return this._syncAmount - } - - get syncFileCount() { - return this._missing.length - } - - _fetch(_url, opts = {}) { - if (opts.useCurrentTeam !== false && this.currentTeam) { - const parsedUrl = parseUrl(_url, true) - const query = parsedUrl.query - - query.teamId = this.currentTeam.id - _url = `${parsedUrl.pathname}?${qs.encode(query)}` - delete opts.useCurrentTeam - } - - opts.headers = opts.headers || {} - opts.headers.authorization = `Bearer ${this._token}` - opts.headers['user-agent'] = ua - return this._agent.fetch(_url, opts) - } - - setScale(nameOrId, scale) { - return this.retry( - async (bail, attempt) => { - if (this._debug) { - console.time( - `> [debug] #${attempt} POST /deployments/${nameOrId}/instances` - ) - } - - const res = await this._fetch( - `/now/deployments/${nameOrId}/instances`, - { - method: 'POST', - body: scale - } - ) - - if (this._debug) { - console.timeEnd( - `> [debug] #${attempt} POST /deployments/${nameOrId}/instances` - ) - } - - if (res.status === 403) { - return bail(new Error('Unauthorized')) - } - - const body = await res.json() - - if (res.status !== 200) { - if (res.status === 404 || res.status === 400) { - if ( - body && - body.error && - body.error.code && - body.error.code === 'not_snapshotted' - ) { - throw new Error(body.error.message) - } - const err = new Error(body.error.message) - err.userError = true - return bail(err) - } - - if (body.error && body.error.message) { - const err = new Error(body.error.message) - err.userError = true - return bail(err) - } - throw new Error( - `Error occurred while scaling. Please try again later` - ) - } - - return body - }, - { - retries: 300, - maxTimeout: ms('5s'), - factor: 1.1 - } - ) - } - - async unfreeze(depl) { - return this.retry(async bail => { - const res = await fetch(`https://${depl.url}`) - - if ([500, 502, 503].includes(res.status)) { - const err = new Error('Unfreeze failed. Try again later.') - bail(err) - } - }) - } - - async getPlanMax() { - return 10 - } -} - -function toRelative(path, base) { - const fullBase = base.endsWith(SEP) ? base : base + SEP - let relative = path.substr(fullBase.length) - - if (relative.startsWith(SEP)) { - relative = relative.substr(1) - } - - return relative.replace(/\\/g, '/') -} - -function hasNpmStart(pkg) { - return pkg.scripts && (pkg.scripts.start || pkg.scripts['now-start']) -} - -function hasFile(base, files, name) { - const relative = files.map(file => toRelative(file, base)) - return relative.indexOf(name) !== -1 -} - -async function readAuthToken(path, name = '.npmrc') { - try { - const contents = await readFile(resolvePath(path, name), 'utf8') - const npmrc = parseIni(contents) - return npmrc['//registry.npmjs.org/:_authToken'] - } catch (err) { - // Do nothing - } -} diff --git a/lib/is-zeit-world.js b/lib/is-zeit-world.js deleted file mode 100644 index 80eea6c..0000000 --- a/lib/is-zeit-world.js +++ /dev/null @@ -1,32 +0,0 @@ -/** - * List of `zeit.world` nameservers - */ - -const nameservers = new Set([ - 'california.zeit.world', - 'london.zeit.world', - 'newark.zeit.world', - 'sydney.zeit.world', - 'iowa.zeit.world', - 'dallas.zeit.world', - 'amsterdam.zeit.world', - 'paris.zeit.world', - 'frankfurt.zeit.world', - 'singapore.zeit.world' -]) - -/** - * Given an array of nameservers (ie: as returned - * by `resolveNs` from Node, assert that they're - * zeit.world's. - */ -function isZeitWorld(ns) { - return ( - ns.length > 1 && - ns.every(host => { - return nameservers.has(host) - }) - ) -} - -module.exports = isZeitWorld diff --git a/lib/login.js b/lib/login.js deleted file mode 100644 index 4dd9fd2..0000000 --- a/lib/login.js +++ /dev/null @@ -1,141 +0,0 @@ -// Native -const os = require('os') - -// Packages -const { stringify: stringifyQuery } = require('querystring') -const chalk = require('chalk') -const fetch = require('node-fetch') -const { validate } = require('email-validator') -const readEmail = require('email-prompt') -const ora = require('ora') - -// Ours -const pkg = require('./pkg') -const ua = require('./ua') -const cfg = require('./cfg') - -async function getVerificationData(url, email) { - const tokenName = `Now CLI ${os.platform()}-${os.arch()} ${pkg.version} (${os.hostname()})` - const data = JSON.stringify({ email, tokenName }) - const res = await fetch(`${url}/now/registration`, { - method: 'POST', - headers: { - 'Content-Type': 'application/json', - 'Content-Length': Buffer.byteLength(data), - 'User-Agent': ua - }, - body: data - }) - - const body = await res.json() - if (res.status !== 200) { - throw new Error( - `Verification error: ${res.status} – ${JSON.stringify(body)}` - ) - } - return body -} - -async function verify(url, email, verificationToken) { - const query = { - email, - token: verificationToken - } - - const res = await fetch( - `${url}/now/registration/verify?${stringifyQuery(query)}`, - { - headers: { 'User-Agent': ua } - } - ) - const body = await res.json() - return body.token -} - -function sleep(ms) { - return new Promise(resolve => { - setTimeout(resolve, ms) - }) -} - -async function register(url, { retryEmail = false } = {}) { - let email - try { - email = await readEmail({ invalid: retryEmail }) - } catch (err) { - process.stdout.write('\n') - throw err - } - - process.stdout.write('\n') - - if (!validate(email)) { - return register(url, { retryEmail: true }) - } - - const { token, securityCode } = await getVerificationData(url, email) - console.log( - `> Please follow the link sent to ${chalk.bold(email)} to log in.` - ) - - if (securityCode) { - console.log( - `> Verify that the provided security code in the email matches ${chalk.cyan( - chalk.bold(securityCode) - )}.` - ) - } - - process.stdout.write('\n') - - const spinner = ora({ - text: 'Waiting for confirmation...' - }).start() - - let final - - /* eslint-disable no-await-in-loop */ - do { - await sleep(2500) - - try { - final = await verify(url, email, token) - } catch (err) {} - } while (!final) - /* eslint-enable no-await-in-loop */ - - let user - try { - user = (await (await fetch(`${url}/www/user`, { - headers: { - Authorization: `Bearer ${final}` - } - })).json()).user - } catch (err) { - spinner.stop() - throw new Error(`Couldn't retrieve user details ${err.message}`) - } - - spinner.text = 'Confirmed email address!' - spinner.stopAndPersist('✔') - - process.stdout.write('\n') - - return { - token: final, - user: { - uid: user.uid, - username: user.username, - email: user.email - }, - lastUpdate: Date.now() - } -} - -module.exports = async function(url) { - const loginData = await register(url) - await cfg.merge(loginData) - await cfg.remove('currentTeam') // Make sure to logout the team too - await cfg.remove('email') // Remove old schema from previus versions - return loginData.token -} diff --git a/lib/logs.js b/lib/logs.js deleted file mode 100644 index a636231..0000000 --- a/lib/logs.js +++ /dev/null @@ -1,14 +0,0 @@ -exports.compare = function(a, b) { - return ( - a.serial.localeCompare(b.serial) || - // For the case serials are a same value on old logs - a.created.getTime() - b.created.getTime() - ) -} - -exports.deserialize = function(log) { - return Object.assign({}, log, { - date: new Date(log.date), - created: new Date(log.created) - }) -} diff --git a/lib/pkg.js b/lib/pkg.js deleted file mode 100644 index 51ff78d..0000000 --- a/lib/pkg.js +++ /dev/null @@ -1,13 +0,0 @@ -/* eslint-disable import/no-unresolved */ - -const path = require('path') -const pkg = require('../package.json') - -try { - const distDir = path.dirname(process.execPath) - pkg._npmPkg = require(path.join(distDir, '../../package.json')) -} catch (err) { - pkg._npmPkg = null -} - -module.exports = pkg diff --git a/lib/plans.js b/lib/plans.js deleted file mode 100644 index 6351312..0000000 --- a/lib/plans.js +++ /dev/null @@ -1,57 +0,0 @@ -const ms = require('ms') - -const Now = require('../lib') - -async function parsePlan(json) { - const { subscription } = json - let id - let until - let name - - if (subscription) { - const planItems = subscription.items.data - const mainPlan = planItems.find(d => d.plan.metadata.is_main_plan === '1') - - if (mainPlan) { - id = mainPlan.plan.id - name = mainPlan.plan.name - if (subscription.cancel_at_period_end) { - until = ms( - new Date(subscription.current_period_end * 1000) - new Date(), - { long: true } - ) - } - } else { - id = 'oss' - } - } else { - id = 'oss' - } - - return { id, name, until } -} - -module.exports = class Plans extends Now { - async getCurrent() { - const res = await this._fetch('/plan') - const json = await res.json() - return parsePlan(json) - } - - async set(plan) { - const res = await this._fetch('/plan', { - method: 'PUT', - body: { plan } - }) - - const json = await res.json() - - if (res.ok) { - return parsePlan(json) - } - - const err = new Error(json.error.message) - err.code = json.error.code - throw err - } -} diff --git a/lib/re-alias.js b/lib/re-alias.js deleted file mode 100644 index 7992396..0000000 --- a/lib/re-alias.js +++ /dev/null @@ -1,134 +0,0 @@ -// Native -const { join } = require('path') - -// Packages -const fs = require('fs-extra') -const chalk = require('chalk') - -// Ours -const { error } = require('./error') -const readMetaData = require('./read-metadata') -const NowAlias = require('./alias') -const NowDomains = require('./domains') - -exports.assignAlias = async ( - autoAlias, - token, - deployment, - apiUrl, - debug, - currentTeam, - user -) => { - const aliases = new NowAlias({ apiUrl, token, debug, currentTeam }) - const domains = new NowDomains({ apiUrl, token, debug, currentTeam }) - console.log( - `> Assigning alias ${chalk.bold.underline(autoAlias)} to deployment...` - ) - - // Assign alias - await aliases.set( - String(deployment), - String(autoAlias), - domains, - currentTeam, - user - ) -} - -exports.reAlias = async ( - token, - host, - pointer, - help, - exit, - apiUrl, - debug, - alias, - currentTeam, - user -) => { - const path = process.cwd() - - const configFiles = { - pkg: join(path, 'package.json'), - nowJSON: join(path, 'now.json') - } - - if (!fs.existsSync(configFiles.pkg) && !fs.existsSync(configFiles.nowJSON)) { - error( - `Couldn't find a now.json or package.json file with an alias list in it` - ) - return - } - - const { nowConfig, name } = await readMetaData(path, { - deploymentType: 'npm', // Hard coding settings… - quiet: true // `quiet` - }) - - if (!host) { - const lastAlias = await alias.last(name) - host = lastAlias.url - } - - if (!nowConfig) { - help() - return exit(0) - } - - let pointers = [] - - if (pointer) { - pointers.push(pointer) - } else { - if (nowConfig.alias) { - const value = nowConfig.alias - - if (typeof value === 'string') { - pointers.push(value) - } else if (Array.isArray(value)) { - pointers = pointers.concat(nowConfig.alias) - } else { - error( - `Property ${chalk.grey('aliases')} is not a valid array or string` - ) - return exit(1) - } - } - - if (nowConfig.aliases && Array.isArray(nowConfig.aliases)) { - console.log( - `${chalk.red('Deprecated!')} The property ${chalk.grey( - 'aliases' - )} will be removed from the config file soon.` - ) - console.log('Read more about the new way here: http://bit.ly/2l2v5Fg\n') - - pointers = pointers.concat(nowConfig.aliases) - } - } - - if (pointers.length === 0) { - help() - return exit(0) - } - - const assignments = [] - - for (const pointer of pointers) { - assignments.push( - exports.assignAlias( - pointer, - token, - host, - apiUrl, - debug, - currentTeam, - user - ) - ) - } - - await Promise.all(assignments) -} diff --git a/lib/read-metadata.js b/lib/read-metadata.js deleted file mode 100644 index 261399a..0000000 --- a/lib/read-metadata.js +++ /dev/null @@ -1,195 +0,0 @@ -// Native -const { basename, resolve: resolvePath } = require('path') - -// Packages -const chalk = require('chalk') -const { readFile } = require('fs-extra') -const { parse: parseDockerfile } = require('docker-file-parser') -const determineType = require('deployment-type') - -module.exports = readMetaData - -async function readMetaData( - path, - { - deploymentType, - deploymentName, - sessionAffinity, - quiet = false, - strict = true - } -) { - let description - let type = deploymentType - let name = deploymentName - let affinity = sessionAffinity - - const pkg = await readJSON(path, 'package.json') - let nowConfig = await readJSON(path, 'now.json') - const dockerfile = await readDockerfile(path) - - const hasNowJson = Boolean(nowConfig) - - if (pkg && pkg.now) { - // If the project has both a `now.json` and `now` Object in the `package.json` - // file, then fail hard and let the user know that they need to pick one or the - // other - if (nowConfig) { - const err = new Error( - 'You have a `now` configuration field inside `package.json` ' + - 'but configuration is also present in `now.json`! ' + - "Please ensure there's a single source of configuration by removing one." - ) - err.userError = true - throw err - } else { - nowConfig = pkg.now - } - } - - // We can remove this once the prompt for choosing `--npm` or `--docker` is gone - if (pkg && pkg.now && pkg.now.type) { - type = nowConfig.type - } - - // The same goes for this - if (nowConfig && nowConfig.type) { - type = nowConfig.type - } - - if (!type) { - type = await determineType(path) - - // Both `package.json` and `Dockerfile` exist! Prompt the user to pick one. - // We can remove this soon (details are internal) - also read the comment paragraph above - if (type === 'docker' && (pkg && dockerfile)) { - const err = new Error( - 'Ambiguous deployment (`package.json` and `Dockerfile` found). ' + - 'Please supply `--npm` or `--docker` to disambiguate.' - ) - - err.userError = true - err.code = 'MULTIPLE_MANIFESTS' - - throw err - } - } - - if (!name && nowConfig) { - name = nowConfig.name - } - - if (!affinity && nowConfig) { - affinity = nowConfig.sessionAffinity - } - - if (type === 'npm') { - if (pkg) { - if (!name && pkg.now && pkg.now.name) { - name = String(pkg.now.name) - } - - if (!name && pkg.name) { - name = String(pkg.name) - } - - description = pkg.description - } - } else if (type === 'docker') { - if (strict && dockerfile.length <= 0) { - const err = new Error('No commands found in `Dockerfile`') - err.userError = true - - throw err - } - - const labels = {} - - dockerfile.filter(cmd => cmd.name === 'LABEL').forEach(({ args }) => { - for (const key in args) { - if (!{}.hasOwnProperty.call(args, key)) { - continue - } - - // Unescape and convert into string - try { - labels[key] = args[key] - } catch (err) { - const e = new Error( - `Error parsing value for LABEL ${key} in \`Dockerfile\`` - ) - - e.userError = true - throw e - } - } - }) - - if (!name) { - name = labels.name - } - - description = labels.description - } else if (type === 'static') { - // Do nothing - } else { - throw new TypeError(`Unsupported "deploymentType": ${type}`) - } - - // No name in `package.json` / `now.json`, or "name" label in Dockerfile. - // Default to the basename of the root dir - if (!name) { - name = basename(path) - - if (!quiet && type !== 'static') { - if (type === 'docker') { - console.log( - `> No \`name\` LABEL in \`Dockerfile\`, using ${chalk.bold(name)}` - ) - } else { - console.log( - `> No \`name\` in \`package.json\`, using ${chalk.bold(name)}` - ) - } - } - } - - return { - name, - description, - type, - pkg, - nowConfig, - hasNowJson, - - // XXX: legacy - deploymentType: type, - sessionAffinity: affinity - } -} - -async function readJSON(path, name) { - try { - const contents = await readFile(resolvePath(path, name), 'utf8') - return JSON.parse(contents) - } catch (err) { - // If the file doesn't exist then that's fine; any other error bubbles up - if (err.code !== 'ENOENT') { - err.userError = true - throw err - } - } -} - -async function readDockerfile(path, name = 'Dockerfile') { - try { - const contents = await readFile(resolvePath(path, name), 'utf8') - return parseDockerfile(contents, { includeComments: true }) - } catch (err) { - // If the file doesn't exist then that's fine; any other error bubbles up - if (err.code !== 'ENOENT') { - err.userError = true - throw err - } - } -} diff --git a/lib/scale-info.js b/lib/scale-info.js deleted file mode 100644 index ef57670..0000000 --- a/lib/scale-info.js +++ /dev/null @@ -1,78 +0,0 @@ -const linelog = require('single-line-log').stdout -const range = require('lodash.range') -const ms = require('ms') -const chalk = require('chalk') -const retry = require('async-retry') - -function barify(cur, tot) { - return ( - '[' + - range(0, cur).map(() => '=').join('') + - range(cur, tot).map(() => '-').join('') + - ']' - ) -} - -module.exports = async function(now, url) { - const match = await now.findDeployment(url) - const { min, max, current } = match.scale - - let targetReplicaCount = min - if (current < min) { - targetReplicaCount = min - } else if (current > max) { - targetReplicaCount = max - } else { - return - } - - if (targetReplicaCount === 0) { - console.log(`> Scaled to 0 instances`) - return - } - const startTime = Date.now() - - let barcurr = current - const end = Math.max(current, max) - linelog( - `${chalk.gray('>')} Scaling to ${chalk.bold( - String(targetReplicaCount) + - (targetReplicaCount === 1 ? ' instance' : ' instances') - )}: ` + barify(barcurr, end) - ) - - const instances = await retry( - async () => { - const res = await now.listInstances(match.uid) - if (barcurr !== res.length) { - barcurr = res.length - linelog( - `${chalk.gray('>')} Scaling to ${chalk.bold( - String(targetReplicaCount) + - (targetReplicaCount === 1 ? ' instance' : ' instances') - )}: ` + barify(barcurr, end) - ) - - if (barcurr === targetReplicaCount) { - linelog.clear() - linelog( - `> Scaled to ${chalk.bold( - String(targetReplicaCount) + - (targetReplicaCount === 1 ? ' instance' : ' instances') - )}: ${chalk.gray('[' + ms(Date.now() - startTime) + ']')}\n` - ) - return res - } - } - - throw new Error('Not ready yet') - }, - { retries: 5000, minTimeout: 10, maxTimeout: 20 } - ) - - process.nextTick(() => { - instances.forEach(inst => { - console.log(`${chalk.gray('-')} ${chalk.underline(inst.url)}`) - }) - }) -} diff --git a/lib/scale.js b/lib/scale.js deleted file mode 100644 index ba577f0..0000000 --- a/lib/scale.js +++ /dev/null @@ -1,40 +0,0 @@ -// Ours -const Now = require('../lib') - -module.exports = class Scale extends Now { - getInstances(id) { - return this.retry(async (bail, attempt) => { - if (this._debug) { - console.time(`> [debug] #${attempt} GET /deployments/${id}/instances`) - } - - const res = await this._fetch(`/now/deployments/${id}/instances`, { - method: 'GET' - }) - - if (this._debug) { - console.timeEnd( - `> [debug] #${attempt} GET /deployments/${id}/instances` - ) - } - - if (res.status === 403) { - return bail(new Error('Unauthorized')) - } - - const body = await res.json() - - if (res.status !== 200) { - if (res.status === 404 || res.status === 400) { - const err = new Error(body.error.message) - err.userError = true - return bail(err) - } - - throw new Error(body.error.message) - } - - return body - }) - } -} diff --git a/lib/secrets.js b/lib/secrets.js deleted file mode 100644 index 898a60c..0000000 --- a/lib/secrets.js +++ /dev/null @@ -1,119 +0,0 @@ -// Ours -const Now = require('../lib') - -const isUserError = res => ((res.status / 100) | 0) === 4 - -module.exports = class Secrets extends Now { - ls() { - return this.listSecrets() - } - - rm(nameOrId) { - return this.retry(async (bail, attempt) => { - if (this._debug) { - console.time(`> [debug] #${attempt} DELETE /secrets/${nameOrId}`) - } - - const res = await this._fetch(`/now/secrets/${nameOrId}`, { - method: 'DELETE' - }) - - if (this._debug) { - console.timeEnd(`> [debug] #${attempt} DELETE /secrets/${nameOrId}`) - } - - if (res.status === 403) { - return bail(new Error('Unauthorized')) - } - - const body = await res.json() - - if (res.status !== 200) { - if (isUserError(res)) { - const err = new Error(body.error.message) - err.userError = true - return bail(err) - } - - throw new Error(body.error.message) - } - - return body - }) - } - - add(name, value) { - return this.retry(async (bail, attempt) => { - if (this._debug) { - console.time(`> [debug] #${attempt} POST /secrets`) - } - - const res = await this._fetch('/now/secrets', { - method: 'POST', - body: { - name, - value: value.toString() - } - }) - - if (this._debug) { - console.timeEnd(`> [debug] #${attempt} POST /secrets`) - } - - if (res.status === 403) { - return bail(new Error('Unauthorized')) - } - - const body = await res.json() - - if (res.status !== 200) { - if (isUserError(res)) { - const err = new Error(body.error.message) - err.userError = true - return bail(err) - } - - throw new Error(body.error.message) - } - - return body - }) - } - - rename(nameOrId, newName) { - return this.retry(async (bail, attempt) => { - if (this._debug) { - console.time(`> [debug] #${attempt} PATCH /secrets/${nameOrId}`) - } - - const res = await this._fetch(`/now/secrets/${nameOrId}`, { - method: 'PATCH', - body: { - name: newName - } - }) - - if (this._debug) { - console.timeEnd(`> [debug] #${attempt} PATCH /secrets/${nameOrId}`) - } - - if (res.status === 403) { - return bail(new Error('Unauthorized')) - } - - const body = await res.json() - - if (res.status !== 200) { - if (isUserError(res)) { - const err = new Error(body.error.message) - err.userError = true - return bail(err) - } - - throw new Error(body.error.message) - } - - return body - }) - } -} diff --git a/lib/sort-deployments.js b/lib/sort-deployments.js deleted file mode 100644 index 1c70a39..0000000 --- a/lib/sort-deployments.js +++ /dev/null @@ -1,30 +0,0 @@ -const fs = require('fs-extra') - -module.exports = async function(apps) { - let pkg - try { - const json = await fs.readFile('package.json') - pkg = JSON.parse(json) - } catch (err) { - pkg = {} - } - - return apps - .map(([name, deps]) => { - deps = deps.slice().sort((a, b) => { - return b.created - a.created - }) - return [name, deps] - }) - .sort(([nameA, depsA], [nameB, depsB]) => { - if (pkg.name === nameA) { - return -1 - } - - if (pkg.name === nameB) { - return 1 - } - - return depsB[0].created - depsA[0].created - }) -} diff --git a/lib/strlen.js b/lib/strlen.js deleted file mode 100644 index cb1f234..0000000 --- a/lib/strlen.js +++ /dev/null @@ -1,5 +0,0 @@ -function strlen(str) { - return str.replace(/\u001b[^m]*m/g, '').length -} - -module.exports = strlen diff --git a/lib/teams.js b/lib/teams.js deleted file mode 100644 index 794938a..0000000 --- a/lib/teams.js +++ /dev/null @@ -1,139 +0,0 @@ -const Now = require('../lib') - -module.exports = class Teams extends Now { - async create({ slug }) { - return this.retry(async (bail, attempt) => { - if (this._debug) { - console.time(`> [debug] #${attempt} POST /teams}`) - } - - const res = await this._fetch(`/teams`, { - method: 'POST', - body: { - slug - } - }) - - if (this._debug) { - console.timeEnd(`> [debug] #${attempt} POST /teams`) - } - - if (res.status === 403) { - return bail(new Error('Unauthorized')) - } - - const body = await res.json() - - if (res.status === 400) { - const e = new Error(body.error.message) - e.code = body.error.code - return bail(e) - } else if (res.status !== 200) { - const e = new Error(body.error.message) - e.code = body.error.code - throw e - } - - return body - }) - } - - async edit({ id, slug, name }) { - return this.retry(async (bail, attempt) => { - if (this._debug) { - console.time(`> [debug] #${attempt} PATCH /teams/${id}}`) - } - - const payload = {} - if (name) { - payload.name = name - } - if (slug) { - payload.slug = slug - } - - const res = await this._fetch(`/teams/${id}`, { - method: 'PATCH', - body: payload - }) - - if (this._debug) { - console.timeEnd(`> [debug] #${attempt} PATCH /teams/${id}`) - } - - if (res.status === 403) { - return bail(new Error('Unauthorized')) - } - - const body = await res.json() - - if (res.status === 400) { - const e = new Error(body.error.message) - e.code = body.error.code - return bail(e) - } else if (res.status !== 200) { - const e = new Error(body.error.message) - e.code = body.error.code - throw e - } - - return body - }) - } - - async inviteUser({ teamId, email }) { - return this.retry(async (bail, attempt) => { - if (this._debug) { - console.time(`> [debug] #${attempt} POST /teams/${teamId}/members}`) - } - const res = await this._fetch(`/teams/${teamId}/members`, { - method: 'POST', - body: { - email - } - }) - - if (this._debug) { - console.timeEnd(`> [debug] #${attempt} POST /teams/${teamId}/members}`) - } - - if (res.status === 403) { - return bail(new Error('Unauthorized')) - } - - const body = await res.json() - - if (res.status === 400) { - const e = new Error(body.error.message) - e.code = body.error.code - return bail(e) - } else if (res.status !== 200) { - const e = new Error(body.error.message) - e.code = body.error.code - throw e - } - - return body - }) - } - - async ls() { - return this.retry(async (bail, attempt) => { - if (this._debug) { - console.time(`> [debug] #${attempt} GET /teams}`) - } - - const res = await this._fetch(`/teams`) - - if (this._debug) { - console.timeEnd(`> [debug] #${attempt} GET /teams`) - } - - if (res.status === 403) { - return bail(new Error('Unauthorized')) - } - - return res.json() - }) - } -} diff --git a/lib/test.js b/lib/test.js deleted file mode 100644 index 03cb803..0000000 --- a/lib/test.js +++ /dev/null @@ -1,22 +0,0 @@ -// Native -const { resolve } = require('path') - -// Ours -const { npm: getFiles } = require('./get-files') - -getFiles(resolve('../mng-test/files-in-package')) - .then(files => { - console.log(files) - - getFiles(resolve('../mng-test/files-in-package-ignore')) - .then(files2 => { - console.log('ignored: ') - console.log(files2) - }) - .catch(err => { - console.log(err.stack) - }) - }) - .catch(err => { - console.log(err.stack) - }) diff --git a/lib/to-host.js b/lib/to-host.js deleted file mode 100644 index f0eaf78..0000000 --- a/lib/to-host.js +++ /dev/null @@ -1,20 +0,0 @@ -// Native -const { parse } = require('url') - -/** - * Converts a valid deployment lookup parameter to a hostname. - * `http://google.com` => google.com - * google.com => google.com - */ - -function toHost(url) { - if (/^https?:\/\//.test(url)) { - return parse(url).host - } - - // Remove any path if present - // `a.b.c/` => `a.b.c` - return url.replace(/(\/\/)?([^/]+)(.*)/, '$2') -} - -module.exports = toHost diff --git a/lib/ua.js b/lib/ua.js deleted file mode 100644 index 461af42..0000000 --- a/lib/ua.js +++ /dev/null @@ -1,7 +0,0 @@ -// Native -const os = require('os') - -// Ours -const { version } = require('./pkg') - -module.exports = `now ${version} node-${process.version} ${os.platform()} (${os.arch()})` diff --git a/lib/user.js b/lib/user.js deleted file mode 100644 index 4c648b1..0000000 --- a/lib/user.js +++ /dev/null @@ -1,69 +0,0 @@ -const _fetch = require('node-fetch') -const { responseError } = require('./error') - -function _filter(data) { - data = data.user - - return { - uid: data.uid, - username: data.username, - email: data.email - } -} - -/** - * Gets all the info we have about an user - * - * @param {Object} fetch Optionally, _our_ `fetch` can be passed here - * @param {String} token Only necessary if `fetch` is undefined - * @param {String} apiUrl Only necessary if `fetch` is undefined - * @param {Boolean} filter If `true`, the `filter` used will to the data - * before returning - * @return {Object} - */ -async function get( - { fetch, token, apiUrl = 'https://api.zeit.co', filter = true } = {} -) { - let headers = {} - const endpoint = '/www/user' - const url = fetch ? endpoint : apiUrl + endpoint - - if (!fetch) { - headers = { - Authorization: `Bearer ${token}` - } - fetch = _fetch - } - - const res = await fetch(url, { headers }) - - if (res.status === 403) { - const err = Error( - 'Your authentication token is invalid. Try running `now login` to log in again.' - ) - err.userError = true - throw err - } - - if (res.status >= 400 && res.status < 500) { - const err = await responseError(res) - throw err - } - - if (res.status !== 200) { - throw new Error('API Error getting user data') - } - - const json = await res.json() - - if (filter) { - return _filter(json) - } - - return json -} - -module.exports = { - get, - filter: _filter -} diff --git a/lib/utils/billing/card-brands.json b/lib/utils/billing/card-brands.json deleted file mode 100644 index 8bf68a3..0000000 --- a/lib/utils/billing/card-brands.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "VISA": "Visa", - "MASTERCARD": "MasterCard", - "AMERICANEXPRESS": "American Express", - "DINERSCLUB": "Diners Club", - "DISCOVER": "Discover", - "JCB": "JCB" -} diff --git a/lib/utils/billing/country-list.json b/lib/utils/billing/country-list.json deleted file mode 100644 index 605f6f3..0000000 --- a/lib/utils/billing/country-list.json +++ /dev/null @@ -1,251 +0,0 @@ -{ - "United States": "US", - "Afghanistan": "AF", - "Åland Islands": "AX", - "Albania": "AL", - "Algeria": "DZ", - "American Samoa": "AS", - "Andorra": "AD", - "Angola": "AO", - "Anguilla": "AI", - "Antarctica": "AQ", - "Antigua and Barbuda": "AG", - "Argentina": "AR", - "Armenia": "AM", - "Aruba": "AW", - "Australia": "AU", - "Austria": "AT", - "Azerbaijan": "AZ", - "Bahamas": "BS", - "Bahrain": "BH", - "Bangladesh": "BD", - "Barbados": "BB", - "Belarus": "BY", - "Belgium": "BE", - "Belize": "BZ", - "Benin": "BJ", - "Bermuda": "BM", - "Bhutan": "BT", - "Bolivia, Plurinational State of": "BO", - "Bonaire, Sint Eustatius and Saba": "BQ", - "Bosnia and Herzegovina": "BA", - "Botswana": "BW", - "Bouvet Island": "BV", - "Brazil": "BR", - "British Indian Ocean Territory": "IO", - "Brunei Darussalam": "BN", - "Bulgaria": "BG", - "Burkina Faso": "BF", - "Burundi": "BI", - "Cambodia": "KH", - "Cameroon": "CM", - "Canada": "CA", - "Cape Verde": "CV", - "Cayman Islands": "KY", - "Central African Republic": "CF", - "Chad": "TD", - "Chile": "CL", - "China": "CN", - "Christmas Island": "CX", - "Cocos (Keeling) Islands": "CC", - "Colombia": "CO", - "Comoros": "KM", - "Congo": "CG", - "CD": "Congo, the Democratic Republic of the", - "Cook Islands": "CK", - "Costa Rica": "CR", - "Côte d'Ivoire": "CI", - "Croatia": "HR", - "Cuba": "CU", - "Curaçao": "CW", - "Cyprus": "CY", - "Czech Republic": "CZ", - "Denmark": "DK", - "Djibouti": "DJ", - "Dominica": "DM", - "Dominican Republic": "DO", - "Ecuador": "EC", - "Egypt": "EG", - "El Salvador": "SV", - "Equatorial Guinea": "GQ", - "Eritrea": "ER", - "Estonia": "EE", - "Ethiopia": "ET", - "Falkland Islands (Malvinas)": "FK", - "Faroe Islands": "FO", - "Fiji": "FJ", - "Finland": "FI", - "France": "FR", - "French Guiana": "GF", - "French Polynesia": "PF", - "French Southern Territories": "TF", - "Gabon": "GA", - "Gambia": "GM", - "Georgia": "GE", - "Germany": "DE", - "Ghana": "GH", - "Gibraltar": "GI", - "Greece": "GR", - "Greenland": "GL", - "Grenada": "GD", - "Guadeloupe": "GP", - "Guam": "GU", - "Guatemala": "GT", - "Guernsey": "GG", - "Guinea": "GN", - "Guinea-Bissau": "GW", - "Guyana": "GY", - "Haiti": "HT", - "Heard Island and McDonald Islands": "HM", - "Holy See (Vatican City State)": "VA", - "Honduras": "HN", - "Hong Kong": "HK", - "Hungary": "HU", - "Iceland": "IS", - "India": "IN", - "Indonesia": "ID", - "Iran, Islamic Republic of": "IR", - "Iraq": "IQ", - "Ireland": "IE", - "Isle of Man": "IM", - "Israel": "IL", - "Italy": "IT", - "Jamaica": "JM", - "Japan": "JP", - "Jersey": "JE", - "Jordan": "JO", - "Kazakhstan": "KZ", - "Kenya": "KE", - "Kiribati": "KI", - "KP": "Korea, Democratic People's Republic of", - "Korea, Republic of": "KR", - "Kuwait": "KW", - "Kyrgyzstan": "KG", - "Lao People's Democratic Republic": "LA", - "Latvia": "LV", - "Lebanon": "LB", - "Lesotho": "LS", - "Liberia": "LR", - "Libya": "LY", - "Liechtenstein": "LI", - "Lithuania": "LT", - "Luxembourg": "LU", - "Macao": "MO", - "MK": "Macedonia, the former Yugoslav Republic of", - "Madagascar": "MG", - "Malawi": "MW", - "Malaysia": "MY", - "Maldives": "MV", - "Mali": "ML", - "Malta": "MT", - "Marshall Islands": "MH", - "Martinique": "MQ", - "Mauritania": "MR", - "Mauritius": "MU", - "Mayotte": "YT", - "Mexico": "MX", - "Micronesia, Federated States of": "FM", - "Moldova, Republic of": "MD", - "Monaco": "MC", - "Mongolia": "MN", - "Montenegro": "ME", - "Montserrat": "MS", - "Morocco": "MA", - "Mozambique": "MZ", - "Myanmar": "MM", - "Namibia": "NA", - "Nauru": "NR", - "Nepal": "NP", - "Netherlands": "NL", - "New Caledonia": "NC", - "New Zealand": "NZ", - "Nicaragua": "NI", - "Niger": "NE", - "Nigeria": "NG", - "Niue": "NU", - "Norfolk Island": "NF", - "Northern Mariana Islands": "MP", - "Norway": "NO", - "Oman": "OM", - "Pakistan": "PK", - "Palau": "PW", - "Palestinian Territory, Occupied": "PS", - "Panama": "PA", - "Papua New Guinea": "PG", - "Paraguay": "PY", - "Peru": "PE", - "Philippines": "PH", - "Pitcairn": "PN", - "Poland": "PL", - "Portugal": "PT", - "Puerto Rico": "PR", - "Qatar": "QA", - "Réunion": "RE", - "Romania": "RO", - "Russian Federation": "RU", - "Rwanda": "RW", - "Saint Barthélemy": "BL", - "SH": "Saint Helena, Ascension and Tristan da Cunha", - "Saint Kitts and Nevis": "KN", - "Saint Lucia": "LC", - "Saint Martin (French part)": "MF", - "Saint Pierre and Miquelon": "PM", - "Saint Vincent and the Grenadines": "VC", - "Samoa": "WS", - "San Marino": "SM", - "Sao Tome and Principe": "ST", - "Saudi Arabia": "SA", - "Senegal": "SN", - "Serbia": "RS", - "Seychelles": "SC", - "Sierra Leone": "SL", - "Singapore": "SG", - "Sint Maarten (Dutch part)": "SX", - "Slovakia": "SK", - "Slovenia": "SI", - "Solomon Islands": "SB", - "Somalia": "SO", - "South Africa": "ZA", - "GS": "South Georgia and the South Sandwich Islands", - "South Sudan": "SS", - "Spain": "ES", - "Sri Lanka": "LK", - "Sudan": "SD", - "Suriname": "SR", - "Svalbard and Jan Mayen": "SJ", - "Swaziland": "SZ", - "Sweden": "SE", - "Switzerland": "CH", - "Syrian Arab Republic": "SY", - "Taiwan, Province of China": "TW", - "Tajikistan": "TJ", - "Tanzania, United Republic of": "TZ", - "Thailand": "TH", - "Timor-Leste": "TL", - "Togo": "TG", - "Tokelau": "TK", - "Tonga": "TO", - "Trinidad and Tobago": "TT", - "Tunisia": "TN", - "Turkey": "TR", - "Turkmenistan": "TM", - "Turks and Caicos Islands": "TC", - "Tuvalu": "TV", - "Uganda": "UG", - "Ukraine": "UA", - "United Arab Emirates": "AE", - "United Kingdom": "GB", - "UM": "United States Minor Outlying Islands", - "Uruguay": "UY", - "Uzbekistan": "UZ", - "Vanuatu": "VU", - "Venezuela, Bolivarian Republic of": "VE", - "Viet Nam": "VN", - "Virgin Islands, British": "VG", - "Virgin Islands, U.S.": "VI", - "Wallis and Futuna": "WF", - "Western Sahara": "EH", - "Yemen": "YE", - "Zambia": "ZM", -"Zimbabwe": "ZW" -} diff --git a/lib/utils/billing/geocode.js b/lib/utils/billing/geocode.js deleted file mode 100644 index a43fc05..0000000 --- a/lib/utils/billing/geocode.js +++ /dev/null @@ -1,33 +0,0 @@ -// Packages -const gMaps = require('@google/maps') - -const MAPS_API_KEY = 'AIzaSyALfKTQ6AiIoJ8WGDXR3E7IBOwlHoTPfYY' - -// eslint-disable-next-line camelcase -module.exports = function({ country, zipCode: postal_code }) { - return new Promise(resolve => { - const maps = gMaps.createClient({ key: MAPS_API_KEY }) - maps.geocode( - { - address: `${postal_code} ${country}` // eslint-disable-line camelcase - }, - (err, res) => { - if (err || res.json.results.length === 0) { - resolve() - } - - const data = res.json.results[0] - const components = {} - data.address_components.forEach(c => { - components[c.types[0]] = c - }) - const state = components.administrative_area_level_1 - const city = components.locality - resolve({ - state: state && state.long_name, - city: city && city.long_name - }) - } - ) - }) -} diff --git a/lib/utils/check-path.js b/lib/utils/check-path.js deleted file mode 100644 index 8d71267..0000000 --- a/lib/utils/check-path.js +++ /dev/null @@ -1,49 +0,0 @@ -// Native -const os = require('os') -const path = require('path') - -const checkPath = async dir => { - if (!dir) { - return - } - - const home = os.homedir() - let location - - const paths = { - home, - desktop: path.join(home, 'Desktop'), - downloads: path.join(home, 'Downloads') - } - - for (const locationPath in paths) { - if (!{}.hasOwnProperty.call(paths, locationPath)) { - continue - } - - if (dir === paths[locationPath]) { - location = locationPath - } - } - - if (!location) { - return - } - - let locationName - - switch (location) { - case 'home': - locationName = 'user directory' - break - case 'downloads': - locationName = 'downloads directory' - break - default: - locationName = location - } - - throw new Error(`You're trying to deploy your ${locationName}.`) -} - -module.exports = checkPath diff --git a/lib/utils/domains/treat-buy-error.js b/lib/utils/domains/treat-buy-error.js deleted file mode 100644 index 2b9ff53..0000000 --- a/lib/utils/domains/treat-buy-error.js +++ /dev/null @@ -1,29 +0,0 @@ -const error = require('../output/error') - -module.exports = function(err) { - switch (err.code) { - case 'invalid_domain': { - error('Invalid domain') - break - } - case 'not_available': { - error("Domain can't be purchased at this time") - break - } - case 'service_unavailabe': { - error('Purchase failed – Service unavailable') - break - } - case 'unexpected_error': { - error('Purchase failed – Unexpected error') - break - } - case 'forbidden_premium': { - error('A coupon cannot be used to register a premium domain') - break - } - default: { - error(err.message) - } - } -} diff --git a/lib/utils/exit.js b/lib/utils/exit.js deleted file mode 100644 index 62caccb..0000000 --- a/lib/utils/exit.js +++ /dev/null @@ -1,8 +0,0 @@ -module.exports = code => { - // We give stdout some time to flush out - // because there's a node bug where - // stdout writes are asynchronous - // https://github.com/nodejs/node/issues/6456 - /* eslint-disable unicorn/no-process-exit */ - setTimeout(() => process.exit(code || 0), 100) -} diff --git a/lib/utils/fatal-error.js b/lib/utils/fatal-error.js deleted file mode 100644 index 6e35aad..0000000 --- a/lib/utils/fatal-error.js +++ /dev/null @@ -1,7 +0,0 @@ -const error = require('./output/error') -const exit = require('./exit') - -module.exports = (msg, code = 1) => { - error(msg) - exit(code) -} diff --git a/lib/utils/input/list.js b/lib/utils/input/list.js deleted file mode 100644 index d6bf72b..0000000 --- a/lib/utils/input/list.js +++ /dev/null @@ -1,79 +0,0 @@ -const inquirer = require('inquirer') -const stripAnsi = require('strip-ansi') - -// eslint-disable-next-line import/no-unassigned-import -require('./patch-inquirer') - -function getLength(string) { - let biggestLength = 0 - string.split('\n').map(str => { - str = stripAnsi(str) - if (str.length > biggestLength) { - biggestLength = str.length - } - return undefined - }) - return biggestLength -} - -module.exports = async function({ - message = 'the question', - // eslint-disable-line no-unused-vars - choices = [ - { - name: 'something\ndescription\ndetails\netc', - value: 'something unique', - short: 'generally the first line of `name`' - } - ], - pageSize = 15, // Show 15 lines without scrolling (~4 credit cards) - separator = true, // Puts a blank separator between each choice - abort = 'end' // Wether the `abort` option will be at the `start` or the `end` -}) { - let biggestLength = 0 - - choices = choices.map(choice => { - if (choice.name) { - const length = getLength(choice.name) - if (length > biggestLength) { - biggestLength = length - } - return choice - } - throw new Error('Invalid choice') - }) - - if (separator === true) { - choices = choices.reduce( - (prev, curr) => prev.concat(new inquirer.Separator(' '), curr), - [] - ) - } - - const abortSeparator = new inquirer.Separator('─'.repeat(biggestLength)) - const _abort = { - name: 'Abort', - value: undefined - } - - if (abort === 'start') { - const blankSep = choices.shift() - choices.unshift(abortSeparator) - choices.unshift(_abort) - choices.unshift(blankSep) - } else { - choices.push(abortSeparator) - choices.push(_abort) - } - - const nonce = Date.now() - const answer = await inquirer.prompt({ - name: nonce, - type: 'list', - message, - choices, - pageSize - }) - - return answer[nonce] -} diff --git a/lib/utils/input/patch-inquirer.js b/lib/utils/input/patch-inquirer.js deleted file mode 100644 index a869c4f..0000000 --- a/lib/utils/input/patch-inquirer.js +++ /dev/null @@ -1,20 +0,0 @@ -const inquirer = require('inquirer') -const chalk = require('chalk') - -// Here we patch inquirer to use a `>` instead of the ugly green `?` - -/* eslint-disable no-multiple-empty-lines, no-var, no-undef, no-eq-null, eqeqeq, semi */ -const getQuestion = function() { - var message = chalk.bold('> ' + this.opt.message) + ' ' - - // Append the default if available, and if question isn't answered - if (this.opt.default != null && this.status !== 'answered') { - message += chalk.dim('(' + this.opt.default + ') ') - } - - return message -} -/* eslint-enable */ - -inquirer.prompt.prompts.input.prototype.getQuestion = getQuestion -inquirer.prompt.prompts.list.prototype.getQuestion = getQuestion diff --git a/lib/utils/input/prompt-bool.js b/lib/utils/input/prompt-bool.js deleted file mode 100644 index 576b44f..0000000 --- a/lib/utils/input/prompt-bool.js +++ /dev/null @@ -1,58 +0,0 @@ -const chalk = require('chalk') - -module.exports = ( - label, - { - defaultValue = false, - abortSequences = new Set(['\u0003']), - resolveChars = new Set(['\r']), - yesChar = 'y', - noChar = 'n', - stdin = process.stdin, - stdout = process.stdout, - trailing = '' - } = {} -) => { - return new Promise(resolve => { - const isRaw = stdin.isRaw - - stdin.setRawMode(true) - stdin.resume() - - function restore() { - stdout.write(trailing) - stdin.setRawMode(isRaw) - stdin.pause() - stdin.removeListener('data', onData) - } - - function onData(buffer) { - const data = buffer.toString() - - if (data[0].toLowerCase() === yesChar) { - restore() - resolve(true) - } else if (data[0].toLowerCase() === noChar) { - restore() - resolve(false) - } else if (abortSequences.has(data)) { - restore() - resolve(false) - } else if (resolveChars.has(data[0])) { - restore() - resolve(defaultValue) - } else { - // ignore extraneous input - } - } - - const defaultText = - defaultValue === null - ? `[${yesChar}|${noChar}]` - : defaultValue - ? `[${chalk.bold(yesChar.toUpperCase())}|${noChar}]` - : `[${yesChar}|${chalk.bold(noChar.toUpperCase())}]` - stdout.write(`${chalk.gray('>')} ${label} ${chalk.gray(defaultText)} `) - stdin.on('data', onData) - }) -} diff --git a/lib/utils/input/prompt-options.js b/lib/utils/input/prompt-options.js deleted file mode 100644 index a698a99..0000000 --- a/lib/utils/input/prompt-options.js +++ /dev/null @@ -1,39 +0,0 @@ -// Packages -const chalk = require('chalk') - -module.exports = promptOptions - -function promptOptions(opts) { - return new Promise((resolve, reject) => { - opts.forEach(([, text], i) => { - console.log(`${chalk.gray('>')} [${chalk.bold(i + 1)}] ${text}`) - }) - - const ondata = v => { - const s = v.toString() - - const cleanup = () => { - process.stdin.setRawMode(false) - process.stdin.removeListener('data', ondata) - } - - // Ctrl + C - if (s === '\u0003') { - cleanup() - const err = new Error('Aborted') - err.code = 'USER_ABORT' - return reject(err) - } - - const n = Number(s) - if (opts[n - 1]) { - cleanup() - resolve(opts[n - 1][0]) - } - } - - process.stdin.setRawMode(true) - process.stdin.resume() - process.stdin.on('data', ondata) - }) -} diff --git a/lib/utils/input/regexes.js b/lib/utils/input/regexes.js deleted file mode 100644 index aee4f9c..0000000 --- a/lib/utils/input/regexes.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - email: /.+@.+\..+$/ -} diff --git a/lib/utils/input/text.js b/lib/utils/input/text.js deleted file mode 100644 index f8d4540..0000000 --- a/lib/utils/input/text.js +++ /dev/null @@ -1,262 +0,0 @@ -// Packages -const ansiEscapes = require('ansi-escapes') -const ansiRegex = require('ansi-regex') -const chalk = require('chalk') -const stripAnsi = require('strip-ansi') - -// Utilities -const eraseLines = require('../output/erase-lines') - -const ESCAPES = { - LEFT: '\u001B[D', - RIGHT: '\u001B[C', - CTRL_C: '\u0003', - BACKSPACE: '\u0008', - CTRL_H: '\u007F', - CARRIAGE: '\r' -} - -const formatCC = data => { - return data.replace(/\s/g, '').replace(/(.{4})/g, '$1 ').trim() -} - -module.exports = function( - { - label = '', - initialValue = '', - // If false, the `- label` will be printed as `✖ label` in red - // Until the first keypress - valid = true, - // Can be: - // - `false`, which does nothing - // - `cc`, for credit cards - // - `date`, for dates in the mm / yyyy format - mask = false, - placeholder = '', - abortSequences = new Set(['\x03']), - eraseSequences = new Set([ESCAPES.BACKSPACE, ESCAPES.CTRL_H]), - resolveChars = new Set([ESCAPES.CARRIAGE]), - stdin = process.stdin, - stdout = process.stdout, - // Char to print before resolving/rejecting the promise - // If `false`, nothing will be printed - trailing = ansiEscapes.eraseLines(1), - // Gets called on each keypress; - // `data` contains the current keypress; - // `futureValue` contains the current value + the - // Keypress in the correct place - validateKeypress = (data, futureValue) => true, // eslint-disable-line no-unused-vars - // Get's called before the promise is resolved - // Returning `false` here will prevent the user from submiting the value - validateValue = data => true, // eslint-disable-line no-unused-vars - // Receives the value of the input and should return a string - // Or false if no autocomplion is available - autoComplete = value => false, // eslint-disable-line no-unused-vars - // Tab - // Right arrow - autoCompleteChars = new Set(['\t', '\x1b[C']), - // If true, converts everything the user types to to lowercase - forceLowerCase = false - } = {} -) { - return new Promise((resolve, reject) => { - const isRaw = process.stdin.isRaw - - let value - let caretOffset = 0 - let regex - let suggestion = '' - - if (valid) { - stdout.write(label) - } else { - const _label = label.replace('-', '✖') - stdout.write(chalk.red(_label)) - } - - value = initialValue - stdout.write(initialValue) - - if (mask) { - if (!value) { - value = chalk.gray(placeholder) - caretOffset = 0 - stripAnsi(value).length - stdout.write(value) - stdout.write(ansiEscapes.cursorBackward(Math.abs(caretOffset))) - } - - regex = placeholder - .split('') - .reduce((prev, curr) => { - if (curr !== ' ' && !prev.includes(curr)) { - if (curr === '/') { - prev.push(' / ') - } else { - prev.push(curr) - } - } - return prev - }, []) - .join('|') - regex = new RegExp(`(${regex})`, 'g') - } - - stdin.setRawMode(true) - stdin.resume() - - function restore() { - stdin.setRawMode(isRaw) - stdin.pause() - stdin.removeListener('data', onData) - if (trailing) { - stdout.write(trailing) - } - } - - async function onData(buffer) { - let data = buffer.toString() - - value = stripAnsi(value) - - if (abortSequences.has(data)) { - restore() - return reject(new Error('USER_ABORT')) - } - - if (forceLowerCase) { - data = data.toLowerCase() - } - - if (suggestion !== '' && !caretOffset && autoCompleteChars.has(data)) { - value += stripAnsi(suggestion) - suggestion = '' - } else if (data === ESCAPES.LEFT) { - if (value.length > Math.abs(caretOffset)) { - caretOffset-- - } - } else if (data === ESCAPES.RIGHT) { - if (caretOffset < 0) { - caretOffset++ - } - } else if (eraseSequences.has(data)) { - let char - if (mask && value.length > Math.abs(caretOffset)) { - if (value[value.length + caretOffset - 1] === ' ') { - if (value[value.length + caretOffset - 2] === '/') { - caretOffset -= 1 - } - char = placeholder[value.length + caretOffset] - value = - value.substr(0, value.length + caretOffset - 2) + - char + - value.substr(value.length + caretOffset - 1) - caretOffset-- - } else { - char = placeholder[value.length + caretOffset - 1] - value = - value.substr(0, value.length + caretOffset - 1) + - char + - value.substr(value.length + caretOffset) - } - caretOffset-- - } else { - value = - value.substr(0, value.length + caretOffset - 1) + - value.substr(value.length + caretOffset) - } - suggestion = '' - } else if (resolveChars.has(data)) { - if (validateValue(value)) { - restore() - resolve(value) - } else { - if (mask === 'cc' || mask === 'ccv') { - value = formatCC(value) - value = value.replace(regex, chalk.gray('$1')) - } else if (mask === 'expDate') { - value = value.replace(regex, chalk.gray('$1')) - } - - const l = chalk.red(label.replace('-', '✖')) - eraseLines(1) - stdout.write(l + value + ansiEscapes.beep) - if (caretOffset) { - process.stdout.write( - ansiEscapes.cursorBackward(Math.abs(caretOffset)) - ) - } - } - return - } else if (!ansiRegex().test(data)) { - let tmp = - value.substr(0, value.length + caretOffset) + - data + - value.substr(value.length + caretOffset) - - if (mask) { - if (/\d/.test(data) && caretOffset !== 0) { - let formattedData = data - - if (mask === 'cc' || mask === 'ccv') { - formattedData = formatCC(data) - } - - if (value[value.length + caretOffset + 1] === ' ') { - tmp = - value.substr(0, value.length + caretOffset) + - formattedData + - value.substr(value.length + caretOffset + formattedData.length) - - caretOffset += formattedData.length + 1 - - if (value[value.length + caretOffset] === '/') { - caretOffset += formattedData.length + 1 - } - } else { - tmp = - value.substr(0, value.length + caretOffset) + - formattedData + - value.substr(value.length + caretOffset + formattedData.length) - - caretOffset += formattedData.length - } - } else if (/\s/.test(data) && caretOffset < 0) { - caretOffset++ - tmp = value - } else { - return stdout.write(ansiEscapes.beep) - } - value = tmp - } else if (validateKeypress(data, value)) { - value = tmp - if (caretOffset === 0) { - const completion = await autoComplete(value) - if (completion) { - suggestion = chalk.gray(completion) - suggestion += ansiEscapes.cursorBackward(completion.length) - } else { - suggestion = '' - } - } - } else { - return stdout.write(ansiEscapes.beep) - } - } - - if (mask === 'cc' || mask === 'ccv') { - value = formatCC(value) - value = value.replace(regex, chalk.gray('$1')) - } else if (mask === 'expDate') { - value = value.replace(regex, chalk.gray('$1')) - } - - eraseLines(1) - stdout.write(label + value + suggestion) - if (caretOffset) { - process.stdout.write(ansiEscapes.cursorBackward(Math.abs(caretOffset))) - } - } - - stdin.on('data', onData) - }) -} diff --git a/lib/utils/output/chars.js b/lib/utils/output/chars.js deleted file mode 100644 index bec8239..0000000 --- a/lib/utils/output/chars.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - tick: '✓' -} diff --git a/lib/utils/output/cmd.js b/lib/utils/output/cmd.js deleted file mode 100644 index 024ab3c..0000000 --- a/lib/utils/output/cmd.js +++ /dev/null @@ -1,6 +0,0 @@ -const chalk = require('chalk') - -// The equivalent of , for embedding a cmd -// eg: Please run ${cmd(woot)} - -module.exports = cmd => `${chalk.gray('`')}${chalk.cyan(cmd)}${chalk.gray('`')}` diff --git a/lib/utils/output/code.js b/lib/utils/output/code.js deleted file mode 100644 index ed11ab2..0000000 --- a/lib/utils/output/code.js +++ /dev/null @@ -1,6 +0,0 @@ -const chalk = require('chalk') - -// The equivalent of , for embedding anything -// you may want to take a look at ./cmd.js - -module.exports = cmd => `${chalk.gray('`')}${chalk.bold(cmd)}${chalk.gray('`')}` diff --git a/lib/utils/output/erase-lines.js b/lib/utils/output/erase-lines.js deleted file mode 100644 index a7cae20..0000000 --- a/lib/utils/output/erase-lines.js +++ /dev/null @@ -1,3 +0,0 @@ -const ansiEscapes = require('ansi-escapes') - -module.exports = n => process.stdout.write(ansiEscapes.eraseLines(n)) diff --git a/lib/utils/output/error.js b/lib/utils/output/error.js deleted file mode 100644 index d5555c3..0000000 --- a/lib/utils/output/error.js +++ /dev/null @@ -1,9 +0,0 @@ -const chalk = require('chalk') - -// Prints an error message -module.exports = msg => { - if (msg.message) { - msg = msg.message - } - console.error(`${chalk.red('> Error!')} ${msg}`) -} diff --git a/lib/utils/output/info.js b/lib/utils/output/info.js deleted file mode 100644 index 064ecf7..0000000 --- a/lib/utils/output/info.js +++ /dev/null @@ -1,6 +0,0 @@ -const chalk = require('chalk') - -// Prints an informational message -module.exports = msg => { - console.log(`${chalk.gray('>')} ${msg}`) -} diff --git a/lib/utils/output/logo.js b/lib/utils/output/logo.js deleted file mode 100644 index 1b18411..0000000 --- a/lib/utils/output/logo.js +++ /dev/null @@ -1 +0,0 @@ -module.exports = process.platform === 'win32' ? 'Δ' : '𝚫' diff --git a/lib/utils/output/note.js b/lib/utils/output/note.js deleted file mode 100644 index 0c44ac8..0000000 --- a/lib/utils/output/note.js +++ /dev/null @@ -1,6 +0,0 @@ -const chalk = require('chalk') - -// Prints a note -module.exports = msg => { - console.log(`${chalk.yellow('> NOTE:')} ${msg}`) -} diff --git a/lib/utils/output/param.js b/lib/utils/output/param.js deleted file mode 100644 index 7d4c4e7..0000000 --- a/lib/utils/output/param.js +++ /dev/null @@ -1,7 +0,0 @@ -const chalk = require('chalk') - -// Returns a user param in a nice formatting -// e.g.: google.com -> "google.com" (in bold) - -module.exports = param => - chalk.bold(`${chalk.gray('"')}${chalk.bold(param)}${chalk.gray('"')}`) diff --git a/lib/utils/output/right-pad.js b/lib/utils/output/right-pad.js deleted file mode 100644 index 41f7e4b..0000000 --- a/lib/utils/output/right-pad.js +++ /dev/null @@ -1,4 +0,0 @@ -module.exports = (string, n = 0) => { - n -= string.length - return string + ' '.repeat(n > -1 ? n : 0) -} diff --git a/lib/utils/output/stamp.js b/lib/utils/output/stamp.js deleted file mode 100644 index 7d8d430..0000000 --- a/lib/utils/output/stamp.js +++ /dev/null @@ -1,10 +0,0 @@ -const ms = require('ms') -const chalk = require('chalk') - -// Returns a time delta with the right color -// example: `[103ms]` - -module.exports = () => { - const start = new Date() - return () => chalk.gray(`[${ms(new Date() - start)}]`) -} diff --git a/lib/utils/output/success.js b/lib/utils/output/success.js deleted file mode 100644 index b1d1550..0000000 --- a/lib/utils/output/success.js +++ /dev/null @@ -1,6 +0,0 @@ -const chalk = require('chalk') - -// Prints a success message -module.exports = msg => { - console.log(`${chalk.cyan('> Success!')} ${msg}`) -} diff --git a/lib/utils/output/table.js b/lib/utils/output/table.js deleted file mode 100644 index e70c27f..0000000 --- a/lib/utils/output/table.js +++ /dev/null @@ -1,27 +0,0 @@ -const chalk = require('chalk') -const printf = require('printf') - -const printLine = (data, sizes) => - data.reduce((line, col, i) => { - return line + printf(`%-${sizes[i]}s`, col) - }, '') - -// Print a table -module.exports = (fieldNames = [], data = [], margins = []) => { - // Compute size of each column - const sizes = data - .reduce((acc, row) => { - return row.map((col, i) => { - const currentMaxColSize = acc[i] || 0 - const colSize = (col && col.length) || 0 - return Math.max(currentMaxColSize, colSize) - }) - }, fieldNames.map(col => col.length)) - // Add margin to all columns except the last - .map((size, i) => (i < margins.length && size + margins[i]) || size) - - // Print header - console.log(chalk.grey(printLine(fieldNames, sizes))) - // Print content - data.forEach(row => console.log(printLine(row, sizes))) -} diff --git a/lib/utils/output/uid.js b/lib/utils/output/uid.js deleted file mode 100644 index c651e5f..0000000 --- a/lib/utils/output/uid.js +++ /dev/null @@ -1,5 +0,0 @@ -const chalk = require('chalk') - -// Used for including uids in the output -// example: `(dom_ji13dj2fih4fi2hf)` -module.exports = id => chalk.gray(`(${id})`) diff --git a/lib/utils/output/wait.js b/lib/utils/output/wait.js deleted file mode 100644 index e5f8c07..0000000 --- a/lib/utils/output/wait.js +++ /dev/null @@ -1,15 +0,0 @@ -const ora = require('ora') -const chalk = require('chalk') -const { eraseLine } = require('ansi-escapes') - -// Prints a spinner followed by the given text -module.exports = msg => { - const spinner = ora(chalk.gray(msg)) - spinner.color = 'gray' - spinner.start() - - return () => { - spinner.stop() - process.stdout.write(eraseLine) - } -} diff --git a/lib/utils/to-human-path.js b/lib/utils/to-human-path.js deleted file mode 100644 index e7c280a..0000000 --- a/lib/utils/to-human-path.js +++ /dev/null @@ -1,18 +0,0 @@ -// Native -const { resolve } = require('path') -const { homedir } = require('os') - -// Cleaned-up `$HOME` (i.e.: no trailing slash) -const HOME = resolve(homedir()) - -/** - * Attempts to show the given path in - * a human-friendly form. For example, - * `/Users/rauchg/test.js` becomes `~/test.js` - */ - -function toHumanPath(path) { - return path.replace(HOME, '~') -} - -module.exports = toHumanPath diff --git a/lib/utils/url.js b/lib/utils/url.js deleted file mode 100644 index 0f45b7c..0000000 --- a/lib/utils/url.js +++ /dev/null @@ -1,28 +0,0 @@ -exports.maybeURL = id => { - // E.g, "appname-asdf" - return id.includes('-') -} - -exports.normalizeURL = u => { - // Normalize URL by removing slash from the end - if (u.slice(-1) === '/') { - u = u.slice(0, -1) - } - - // `url` should match the hostname of the deployment - u = u.replace(/^https:\/\//i, '') - - if (!u.includes('.')) { - // `.now.sh` domain is implied if just the subdomain is given - u += '.now.sh' - } - - return u -} - -exports.parseInstanceURL = u => { - const m = /^(.+)-([a-z0-9]{24})(\.now\.sh)$/.exec(u) - const url = m ? m[1] + m[3] : u - const instanceId = m ? m[2] : null - return [url, instanceId] -} diff --git a/license.md b/license.md deleted file mode 100644 index f998fe0..0000000 --- a/license.md +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2016 Zeit, Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/link/link.js b/link/link.js deleted file mode 100755 index 81db150..0000000 --- a/link/link.js +++ /dev/null @@ -1,11 +0,0 @@ -#!/usr/bin/env node - -try { - // eslint-disable-next-line import/no-unassigned-import - require('../bin/now.js') -} catch (err) { - if (err.code === 'ENOENT' && err.syscall === 'uv_cwd') { - console.error(`Current path doesn't exist!`) - process.exit(1) - } -} diff --git a/link/package-lock.json b/link/package-lock.json deleted file mode 100644 index b5a2296..0000000 --- a/link/package-lock.json +++ /dev/null @@ -1,4 +0,0 @@ -{ - "name": "now", - "lockfileVersion": 1 -} diff --git a/link/package.json b/link/package.json deleted file mode 100644 index 3244a77..0000000 --- a/link/package.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "now", - "license": "MIT", - "description": "The command line interface for Now", - "repository": "zeit/now-cli", - "bin": { - "now": "link.js" - } -} diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index 4172eaa..0000000 --- a/package-lock.json +++ /dev/null @@ -1,9560 +0,0 @@ -{ - "name": "now", - "version": "7.3.1", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@ava/babel-plugin-throws-helper": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@ava/babel-plugin-throws-helper/-/babel-plugin-throws-helper-2.0.0.tgz", - "integrity": "sha1-L8H+PCEacQcaTsp7j3r1hCzRrnw=", - "dev": true - }, - "@ava/babel-preset-stage-4": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@ava/babel-preset-stage-4/-/babel-preset-stage-4-1.1.0.tgz", - "integrity": "sha512-oWqTnIGXW3k72UFidXzW0ONlO7hnO9x02S/QReJ7NBGeiBH9cUHY9+EfV6C8PXC6YJH++WrliEq03wMSJGNZFg==", - "dev": true, - "requires": { - "babel-plugin-check-es2015-constants": "6.22.0", - "babel-plugin-syntax-trailing-function-commas": "6.22.0", - "babel-plugin-transform-async-to-generator": "6.24.1", - "babel-plugin-transform-es2015-destructuring": "6.23.0", - "babel-plugin-transform-es2015-function-name": "6.24.1", - "babel-plugin-transform-es2015-modules-commonjs": "6.24.1", - "babel-plugin-transform-es2015-parameters": "6.24.1", - "babel-plugin-transform-es2015-spread": "6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "6.24.1", - "babel-plugin-transform-es2015-unicode-regex": "6.24.1", - "babel-plugin-transform-exponentiation-operator": "6.24.1", - "package-hash": "1.2.0" - }, - "dependencies": { - "md5-hex": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-1.3.0.tgz", - "integrity": "sha1-0sSv6YPENwZiF5uMrRRSGRNQRsQ=", - "dev": true, - "requires": { - "md5-o-matic": "0.1.1" - } - }, - "package-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-1.2.0.tgz", - "integrity": "sha1-AD5WzVe3NqbtYRTMK4FUJnJ3DkQ=", - "dev": true, - "requires": { - "md5-hex": "1.3.0" - } - } - } - }, - "@ava/babel-preset-transform-test-files": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@ava/babel-preset-transform-test-files/-/babel-preset-transform-test-files-3.0.0.tgz", - "integrity": "sha1-ze0RlqjY2TgaUJJAq5LpGl7Aafc=", - "dev": true, - "requires": { - "@ava/babel-plugin-throws-helper": "2.0.0", - "babel-plugin-espower": "2.3.2" - } - }, - "@ava/write-file-atomic": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ava/write-file-atomic/-/write-file-atomic-2.2.0.tgz", - "integrity": "sha512-BTNB3nGbEfJT+69wuqXFr/bQH7Vr7ihx2xGOMNqPgDGhwspoZhiWumDDZNjBy7AScmqS5CELIOGtPVXESyrnDA==", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "imurmurhash": "0.1.4", - "slide": "1.1.6" - } - }, - "@concordance/react": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@concordance/react/-/react-1.0.0.tgz", - "integrity": "sha512-htrsRaQX8Iixlsek8zQU7tE8wcsTQJ5UhZkSPEA8slCDAisKpC/2VgU/ucPn32M5/LjGGXRaUEKvEw1Wiuu4zQ==", - "dev": true, - "requires": { - "arrify": "1.0.1" - } - }, - "@google/maps": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/@google/maps/-/maps-0.4.3.tgz", - "integrity": "sha1-tGiWERTW4HScFYAuDaFJ3Ooig6U=", - "dev": true - }, - "acorn": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.1.1.tgz", - "integrity": "sha512-vOk6uEMctu0vQrvuSqFdJyqj1Q0S5VTDL79qtjo+DhRr+1mmaD+tluFSCZqhvi/JUhXSzoZN2BhtstaPEeE8cw==", - "dev": true - }, - "acorn-dynamic-import": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz", - "integrity": "sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ=", - "dev": true, - "requires": { - "acorn": "4.0.13" - }, - "dependencies": { - "acorn": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-4.0.13.tgz", - "integrity": "sha1-EFSVrlNh1pe9GVyCUZLhrX8lN4c=", - "dev": true - } - } - }, - "acorn-jsx": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", - "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", - "dev": true, - "requires": { - "acorn": "3.3.0" - }, - "dependencies": { - "acorn": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", - "dev": true - } - } - }, - "after": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz", - "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8=", - "dev": true - }, - "ajv": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz", - "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=", - "dev": true, - "requires": { - "co": "4.6.0", - "json-stable-stringify": "1.0.1" - } - }, - "ajv-keywords": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.0.tgz", - "integrity": "sha1-opbhf3v658HOT34N5T0pyzIWLfA=", - "dev": true - }, - "align-text": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz", - "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=", - "dev": true, - "requires": { - "kind-of": "3.2.2", - "longest": "1.0.1", - "repeat-string": "1.6.1" - } - }, - "alpha-sort": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/alpha-sort/-/alpha-sort-2.0.1.tgz", - "integrity": "sha1-UNNTiUfPcOvMFaa0YfsE//O/Htk=", - "dev": true - }, - "amdefine": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz", - "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=", - "dev": true, - "optional": true - }, - "ansi-align": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", - "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", - "dev": true, - "requires": { - "string-width": "2.1.1" - } - }, - "ansi-escapes": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-2.0.0.tgz", - "integrity": "sha1-W65SvkJIeN2Xg+iRDj/Cki6DyBs=", - "dev": true - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", - "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", - "dev": true, - "requires": { - "color-convert": "1.9.0" - } - }, - "anymatch": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz", - "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==", - "dev": true, - "requires": { - "micromatch": "2.3.11", - "normalize-path": "2.1.1" - } - }, - "app-root-path": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/app-root-path/-/app-root-path-2.0.1.tgz", - "integrity": "sha1-zWLc+OT9WkF+/GZNLlsQZTxlG0Y=", - "dev": true - }, - "argparse": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", - "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", - "dev": true, - "requires": { - "sprintf-js": "1.0.3" - } - }, - "arr-diff": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz", - "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=", - "dev": true, - "requires": { - "arr-flatten": "1.1.0" - } - }, - "arr-exclude": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/arr-exclude/-/arr-exclude-1.0.0.tgz", - "integrity": "sha1-38fC5VKicHI8zaBM8xKMjL/lxjE=", - "dev": true - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "array-differ": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz", - "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", - "dev": true - }, - "array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", - "dev": true - }, - "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", - "dev": true, - "requires": { - "array-uniq": "1.0.3" - } - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "arraybuffer.slice": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.6.tgz", - "integrity": "sha1-8zshWfBTKj8xB6JywMz70a0peco=", - "dev": true - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", - "dev": true - }, - "asn1": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", - "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", - "dev": true - }, - "asn1.js": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.1.tgz", - "integrity": "sha1-SLokC0WpKA6UdImQull9IWYX/UA=", - "dev": true, - "requires": { - "bn.js": "4.11.7", - "inherits": "2.0.3", - "minimalistic-assert": "1.0.0" - } - }, - "assert": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", - "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", - "dev": true, - "requires": { - "util": "0.10.3" - } - }, - "assert-plus": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz", - "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=", - "dev": true - }, - "async": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz", - "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==", - "dev": true, - "requires": { - "lodash": "4.17.4" - } - }, - "async-each": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.1.tgz", - "integrity": "sha1-GdOGodntxufByF04iu28xW0zYC0=", - "dev": true - }, - "async-retry": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.1.3.tgz", - "integrity": "sha512-fiAB2uaoAoUS5Ua75XFGoMKF4hmQ5H4u4gsINUjwPNof5dygJS1zyL9mh0SOmIkzAwGijwG4ybLNc8yG2OGpEQ==", - "dev": true, - "requires": { - "retry": "0.10.1" - } - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", - "dev": true - }, - "auto-bind": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/auto-bind/-/auto-bind-1.1.0.tgz", - "integrity": "sha1-k7hk3H7gGjJigXddXHXKCnUeWWE=", - "dev": true - }, - "ava": { - "version": "0.21.0", - "resolved": "https://registry.npmjs.org/ava/-/ava-0.21.0.tgz", - "integrity": "sha512-+ZjahyjqyzkPLlFZe2OoLmiE3aaQ2jK5h74wrkuX5I+J6LpNAPoQ8X/EhqEtKEjuWwmniLAjnVjZ7OY8rWdJwA==", - "dev": true, - "requires": { - "@ava/babel-preset-stage-4": "1.1.0", - "@ava/babel-preset-transform-test-files": "3.0.0", - "@ava/write-file-atomic": "2.2.0", - "@concordance/react": "1.0.0", - "ansi-escapes": "2.0.0", - "ansi-styles": "3.2.0", - "arr-flatten": "1.1.0", - "array-union": "1.0.2", - "array-uniq": "1.0.3", - "arrify": "1.0.1", - "auto-bind": "1.1.0", - "ava-init": "0.2.1", - "babel-core": "6.25.0", - "bluebird": "3.5.0", - "caching-transform": "1.0.1", - "chalk": "2.0.1", - "chokidar": "1.7.0", - "clean-stack": "1.3.0", - "clean-yaml-object": "0.1.0", - "cli-cursor": "2.1.0", - "cli-spinners": "1.0.0", - "cli-truncate": "1.1.0", - "co-with-promise": "4.6.0", - "code-excerpt": "2.1.0", - "common-path-prefix": "1.0.0", - "concordance": "3.0.0", - "convert-source-map": "1.5.0", - "core-assert": "0.2.1", - "currently-unhandled": "0.4.1", - "debug": "2.6.8", - "dot-prop": "4.2.0", - "empower-core": "0.6.2", - "equal-length": "1.0.1", - "figures": "2.0.0", - "find-cache-dir": "1.0.0", - "fn-name": "2.0.1", - "get-port": "3.1.0", - "globby": "6.1.0", - "has-flag": "2.0.0", - "hullabaloo-config-manager": "1.1.1", - "ignore-by-default": "1.0.1", - "import-local": "0.1.1", - "indent-string": "3.2.0", - "is-ci": "1.0.10", - "is-generator-fn": "1.0.0", - "is-obj": "1.0.1", - "is-observable": "0.2.0", - "is-promise": "2.1.0", - "js-yaml": "3.9.0", - "last-line-stream": "1.0.0", - "lodash.clonedeepwith": "4.5.0", - "lodash.debounce": "4.0.8", - "lodash.difference": "4.5.0", - "lodash.flatten": "4.4.0", - "loud-rejection": "1.6.0", - "make-dir": "1.0.0", - "matcher": "1.0.0", - "md5-hex": "2.0.0", - "meow": "3.7.0", - "ms": "2.0.0", - "multimatch": "2.1.0", - "observable-to-promise": "0.5.0", - "option-chain": "1.0.0", - "package-hash": "2.0.0", - "pkg-conf": "2.0.0", - "plur": "2.1.2", - "pretty-ms": "2.1.0", - "require-precompiled": "0.1.0", - "resolve-cwd": "2.0.0", - "safe-buffer": "5.1.1", - "slash": "1.0.0", - "source-map-support": "0.4.15", - "stack-utils": "1.0.1", - "strip-ansi": "4.0.0", - "strip-bom-buf": "1.0.0", - "supports-color": "4.2.1", - "time-require": "0.1.2", - "trim-off-newlines": "1.0.1", - "unique-temp-dir": "1.0.0", - "update-notifier": "2.2.0" - } - }, - "ava-init": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/ava-init/-/ava-init-0.2.1.tgz", - "integrity": "sha512-lXwK5LM+2g1euDRqW1mcSX/tqzY1QU7EjKpqayFPPtNRmbSYZ8RzPO5tqluTToijmtjp2M+pNpVdbcHssC4glg==", - "dev": true, - "requires": { - "arr-exclude": "1.0.0", - "execa": "0.7.0", - "has-yarn": "1.0.0", - "read-pkg-up": "2.0.0", - "write-pkg": "3.1.0" - } - }, - "aws-sign2": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz", - "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=", - "dev": true - }, - "aws4": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz", - "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4=", - "dev": true - }, - "babel-code-frame": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.22.0.tgz", - "integrity": "sha1-AnYgvuVnqIwyVhV05/0IAdMxGOQ=", - "dev": true, - "requires": { - "chalk": "1.1.3", - "esutils": "2.0.2", - "js-tokens": "3.0.2" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "babel-core": { - "version": "6.25.0", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.25.0.tgz", - "integrity": "sha1-fdQrBGPHQunVKW3rPsZ6kyLa1yk=", - "dev": true, - "requires": { - "babel-code-frame": "6.22.0", - "babel-generator": "6.25.0", - "babel-helpers": "6.24.1", - "babel-messages": "6.23.0", - "babel-register": "6.24.1", - "babel-runtime": "6.25.0", - "babel-template": "6.25.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0", - "babylon": "6.17.4", - "convert-source-map": "1.5.0", - "debug": "2.6.8", - "json5": "0.5.1", - "lodash": "4.17.4", - "minimatch": "3.0.4", - "path-is-absolute": "1.0.1", - "private": "0.1.7", - "slash": "1.0.0", - "source-map": "0.5.6" - } - }, - "babel-generator": { - "version": "6.25.0", - "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.25.0.tgz", - "integrity": "sha1-M6GvcNXyiQrrRlpKd5PB32qeqfw=", - "dev": true, - "requires": { - "babel-messages": "6.23.0", - "babel-runtime": "6.25.0", - "babel-types": "6.25.0", - "detect-indent": "4.0.0", - "jsesc": "1.3.0", - "lodash": "4.17.4", - "source-map": "0.5.6", - "trim-right": "1.0.1" - }, - "dependencies": { - "jsesc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", - "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", - "dev": true - } - } - }, - "babel-helper-builder-binary-assignment-operator-visitor": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", - "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", - "dev": true, - "requires": { - "babel-helper-explode-assignable-expression": "6.24.1", - "babel-runtime": "6.25.0", - "babel-types": "6.25.0" - } - }, - "babel-helper-call-delegate": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", - "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", - "dev": true, - "requires": { - "babel-helper-hoist-variables": "6.24.1", - "babel-runtime": "6.25.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0" - } - }, - "babel-helper-define-map": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.24.1.tgz", - "integrity": "sha1-epdH8ljYlH0y1RX2qhx70CIEoIA=", - "dev": true, - "requires": { - "babel-helper-function-name": "6.24.1", - "babel-runtime": "6.25.0", - "babel-types": "6.25.0", - "lodash": "4.17.4" - } - }, - "babel-helper-explode-assignable-expression": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", - "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", - "dev": true, - "requires": { - "babel-runtime": "6.25.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0" - } - }, - "babel-helper-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", - "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", - "dev": true, - "requires": { - "babel-helper-get-function-arity": "6.24.1", - "babel-runtime": "6.25.0", - "babel-template": "6.25.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0" - } - }, - "babel-helper-get-function-arity": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", - "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", - "dev": true, - "requires": { - "babel-runtime": "6.25.0", - "babel-types": "6.25.0" - } - }, - "babel-helper-hoist-variables": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", - "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", - "dev": true, - "requires": { - "babel-runtime": "6.25.0", - "babel-types": "6.25.0" - } - }, - "babel-helper-optimise-call-expression": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", - "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", - "dev": true, - "requires": { - "babel-runtime": "6.25.0", - "babel-types": "6.25.0" - } - }, - "babel-helper-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.24.1.tgz", - "integrity": "sha1-024i+rEAjXnYhkjjIRaGgShFbOg=", - "dev": true, - "requires": { - "babel-runtime": "6.25.0", - "babel-types": "6.25.0", - "lodash": "4.17.4" - } - }, - "babel-helper-remap-async-to-generator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", - "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", - "dev": true, - "requires": { - "babel-helper-function-name": "6.24.1", - "babel-runtime": "6.25.0", - "babel-template": "6.25.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0" - } - }, - "babel-helper-replace-supers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", - "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", - "dev": true, - "requires": { - "babel-helper-optimise-call-expression": "6.24.1", - "babel-messages": "6.23.0", - "babel-runtime": "6.25.0", - "babel-template": "6.25.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0" - } - }, - "babel-helpers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", - "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", - "dev": true, - "requires": { - "babel-runtime": "6.25.0", - "babel-template": "6.25.0" - } - }, - "babel-loader": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-7.1.1.tgz", - "integrity": "sha1-uHE0yLEuPkwqlOBUYIW8aAorhIg=", - "dev": true, - "requires": { - "find-cache-dir": "1.0.0", - "loader-utils": "1.1.0", - "mkdirp": "0.5.1" - } - }, - "babel-messages": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", - "dev": true, - "requires": { - "babel-runtime": "6.25.0" - } - }, - "babel-plugin-check-es2015-constants": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", - "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", - "dev": true, - "requires": { - "babel-runtime": "6.25.0" - } - }, - "babel-plugin-espower": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/babel-plugin-espower/-/babel-plugin-espower-2.3.2.tgz", - "integrity": "sha1-VRa4/NsmyfDh2BYHSfbkxl5xJx4=", - "dev": true, - "requires": { - "babel-generator": "6.25.0", - "babylon": "6.17.4", - "call-matcher": "1.0.1", - "core-js": "2.4.1", - "espower-location-detector": "1.0.0", - "espurify": "1.7.0", - "estraverse": "4.2.0" - } - }, - "babel-plugin-syntax-async-functions": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", - "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=", - "dev": true - }, - "babel-plugin-syntax-exponentiation-operator": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", - "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=", - "dev": true - }, - "babel-plugin-syntax-trailing-function-commas": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", - "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=", - "dev": true - }, - "babel-plugin-transform-async-to-generator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", - "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", - "dev": true, - "requires": { - "babel-helper-remap-async-to-generator": "6.24.1", - "babel-plugin-syntax-async-functions": "6.13.0", - "babel-runtime": "6.25.0" - } - }, - "babel-plugin-transform-es2015-arrow-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", - "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", - "dev": true, - "requires": { - "babel-runtime": "6.25.0" - } - }, - "babel-plugin-transform-es2015-block-scoped-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", - "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", - "dev": true, - "requires": { - "babel-runtime": "6.25.0" - } - }, - "babel-plugin-transform-es2015-block-scoping": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.24.1.tgz", - "integrity": "sha1-dsKV3DpHQbFmWt/TFnIV3P8ypXY=", - "dev": true, - "requires": { - "babel-runtime": "6.25.0", - "babel-template": "6.25.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0", - "lodash": "4.17.4" - } - }, - "babel-plugin-transform-es2015-classes": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", - "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", - "dev": true, - "requires": { - "babel-helper-define-map": "6.24.1", - "babel-helper-function-name": "6.24.1", - "babel-helper-optimise-call-expression": "6.24.1", - "babel-helper-replace-supers": "6.24.1", - "babel-messages": "6.23.0", - "babel-runtime": "6.25.0", - "babel-template": "6.25.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0" - } - }, - "babel-plugin-transform-es2015-computed-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", - "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", - "dev": true, - "requires": { - "babel-runtime": "6.25.0", - "babel-template": "6.25.0" - } - }, - "babel-plugin-transform-es2015-destructuring": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", - "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", - "dev": true, - "requires": { - "babel-runtime": "6.25.0" - } - }, - "babel-plugin-transform-es2015-duplicate-keys": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", - "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", - "dev": true, - "requires": { - "babel-runtime": "6.25.0", - "babel-types": "6.25.0" - } - }, - "babel-plugin-transform-es2015-for-of": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", - "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", - "dev": true, - "requires": { - "babel-runtime": "6.25.0" - } - }, - "babel-plugin-transform-es2015-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", - "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", - "dev": true, - "requires": { - "babel-helper-function-name": "6.24.1", - "babel-runtime": "6.25.0", - "babel-types": "6.25.0" - } - }, - "babel-plugin-transform-es2015-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", - "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", - "dev": true, - "requires": { - "babel-runtime": "6.25.0" - } - }, - "babel-plugin-transform-es2015-modules-amd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", - "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", - "dev": true, - "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "6.24.1", - "babel-runtime": "6.25.0", - "babel-template": "6.25.0" - } - }, - "babel-plugin-transform-es2015-modules-commonjs": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.24.1.tgz", - "integrity": "sha1-0+MQtA72ZKNmIiAAl8bUQCmPK/4=", - "dev": true, - "requires": { - "babel-plugin-transform-strict-mode": "6.24.1", - "babel-runtime": "6.25.0", - "babel-template": "6.25.0", - "babel-types": "6.25.0" - } - }, - "babel-plugin-transform-es2015-modules-systemjs": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", - "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", - "dev": true, - "requires": { - "babel-helper-hoist-variables": "6.24.1", - "babel-runtime": "6.25.0", - "babel-template": "6.25.0" - } - }, - "babel-plugin-transform-es2015-modules-umd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", - "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", - "dev": true, - "requires": { - "babel-plugin-transform-es2015-modules-amd": "6.24.1", - "babel-runtime": "6.25.0", - "babel-template": "6.25.0" - } - }, - "babel-plugin-transform-es2015-object-super": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", - "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", - "dev": true, - "requires": { - "babel-helper-replace-supers": "6.24.1", - "babel-runtime": "6.25.0" - } - }, - "babel-plugin-transform-es2015-parameters": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", - "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", - "dev": true, - "requires": { - "babel-helper-call-delegate": "6.24.1", - "babel-helper-get-function-arity": "6.24.1", - "babel-runtime": "6.25.0", - "babel-template": "6.25.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0" - } - }, - "babel-plugin-transform-es2015-shorthand-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", - "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", - "dev": true, - "requires": { - "babel-runtime": "6.25.0", - "babel-types": "6.25.0" - } - }, - "babel-plugin-transform-es2015-spread": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", - "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", - "dev": true, - "requires": { - "babel-runtime": "6.25.0" - } - }, - "babel-plugin-transform-es2015-sticky-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", - "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", - "dev": true, - "requires": { - "babel-helper-regex": "6.24.1", - "babel-runtime": "6.25.0", - "babel-types": "6.25.0" - } - }, - "babel-plugin-transform-es2015-template-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", - "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", - "dev": true, - "requires": { - "babel-runtime": "6.25.0" - } - }, - "babel-plugin-transform-es2015-typeof-symbol": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", - "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", - "dev": true, - "requires": { - "babel-runtime": "6.25.0" - } - }, - "babel-plugin-transform-es2015-unicode-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", - "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", - "dev": true, - "requires": { - "babel-helper-regex": "6.24.1", - "babel-runtime": "6.25.0", - "regexpu-core": "2.0.0" - } - }, - "babel-plugin-transform-exponentiation-operator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", - "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", - "dev": true, - "requires": { - "babel-helper-builder-binary-assignment-operator-visitor": "6.24.1", - "babel-plugin-syntax-exponentiation-operator": "6.13.0", - "babel-runtime": "6.25.0" - } - }, - "babel-plugin-transform-regenerator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.24.1.tgz", - "integrity": "sha1-uNowWtQ8PJm0hI5P5AN7dw0jxBg=", - "dev": true, - "requires": { - "regenerator-transform": "0.9.11" - } - }, - "babel-plugin-transform-runtime": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz", - "integrity": "sha1-iEkNRGUC6puOfvsP4J7E2ZR5se4=", - "dev": true, - "requires": { - "babel-runtime": "6.25.0" - } - }, - "babel-plugin-transform-strict-mode": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", - "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", - "dev": true, - "requires": { - "babel-runtime": "6.25.0", - "babel-types": "6.25.0" - } - }, - "babel-preset-es2015": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz", - "integrity": "sha1-1EBQ1rwsn+6nAqrzjXJ6AhBTiTk=", - "dev": true, - "requires": { - "babel-plugin-check-es2015-constants": "6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0", - "babel-plugin-transform-es2015-block-scoping": "6.24.1", - "babel-plugin-transform-es2015-classes": "6.24.1", - "babel-plugin-transform-es2015-computed-properties": "6.24.1", - "babel-plugin-transform-es2015-destructuring": "6.23.0", - "babel-plugin-transform-es2015-duplicate-keys": "6.24.1", - "babel-plugin-transform-es2015-for-of": "6.23.0", - "babel-plugin-transform-es2015-function-name": "6.24.1", - "babel-plugin-transform-es2015-literals": "6.22.0", - "babel-plugin-transform-es2015-modules-amd": "6.24.1", - "babel-plugin-transform-es2015-modules-commonjs": "6.24.1", - "babel-plugin-transform-es2015-modules-systemjs": "6.24.1", - "babel-plugin-transform-es2015-modules-umd": "6.24.1", - "babel-plugin-transform-es2015-object-super": "6.24.1", - "babel-plugin-transform-es2015-parameters": "6.24.1", - "babel-plugin-transform-es2015-shorthand-properties": "6.24.1", - "babel-plugin-transform-es2015-spread": "6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "6.24.1", - "babel-plugin-transform-es2015-template-literals": "6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "6.23.0", - "babel-plugin-transform-es2015-unicode-regex": "6.24.1", - "babel-plugin-transform-regenerator": "6.24.1" - } - }, - "babel-register": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.24.1.tgz", - "integrity": "sha1-fhDhOi9xBlvfrVoXh7pFvKbe118=", - "dev": true, - "requires": { - "babel-core": "6.25.0", - "babel-runtime": "6.25.0", - "core-js": "2.4.1", - "home-or-tmp": "2.0.0", - "lodash": "4.17.4", - "mkdirp": "0.5.1", - "source-map-support": "0.4.15" - } - }, - "babel-runtime": { - "version": "6.25.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.25.0.tgz", - "integrity": "sha1-M7mOql1IK7AajRqmtDetKwGuxBw=", - "dev": true, - "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.10.5" - } - }, - "babel-template": { - "version": "6.25.0", - "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.25.0.tgz", - "integrity": "sha1-ZlJBFmt8KqTGGdceGSlpVSsQwHE=", - "dev": true, - "requires": { - "babel-runtime": "6.25.0", - "babel-traverse": "6.25.0", - "babel-types": "6.25.0", - "babylon": "6.17.4", - "lodash": "4.17.4" - } - }, - "babel-traverse": { - "version": "6.25.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.25.0.tgz", - "integrity": "sha1-IldJfi/NGbie3BPEyROB+VEklvE=", - "dev": true, - "requires": { - "babel-code-frame": "6.22.0", - "babel-messages": "6.23.0", - "babel-runtime": "6.25.0", - "babel-types": "6.25.0", - "babylon": "6.17.4", - "debug": "2.6.8", - "globals": "9.18.0", - "invariant": "2.2.2", - "lodash": "4.17.4" - } - }, - "babel-types": { - "version": "6.25.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.25.0.tgz", - "integrity": "sha1-cK+ySNVmDl0Y+BHZHIMDtUE0oY4=", - "dev": true, - "requires": { - "babel-runtime": "6.25.0", - "esutils": "2.0.2", - "lodash": "4.17.4", - "to-fast-properties": "1.0.3" - } - }, - "babylon": { - "version": "6.17.4", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.17.4.tgz", - "integrity": "sha512-kChlV+0SXkjE0vUn9OZ7pBMWRFd8uq3mZe8x1K6jhuNcAFAtEnjchFAqB+dYEXKyd+JpT6eppRR78QAr5gTsUw==", - "dev": true - }, - "backo2": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz", - "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc=", - "dev": true - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true - }, - "base64-arraybuffer": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz", - "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg=", - "dev": true - }, - "base64-js": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz", - "integrity": "sha1-EQHpVE9KdrG8OybUUsqW16NeeXg=", - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", - "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", - "dev": true, - "optional": true, - "requires": { - "tweetnacl": "0.14.5" - } - }, - "better-assert": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz", - "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=", - "dev": true, - "requires": { - "callsite": "1.0.0" - } - }, - "big.js": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.1.3.tgz", - "integrity": "sha1-TK2iGTZS6zyp7I5VyQFWacmAaXg=", - "dev": true - }, - "binary-extensions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.9.0.tgz", - "integrity": "sha1-ZlBsFs5vTWkopbPNajPKQelB43s=", - "dev": true - }, - "bl": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.1.tgz", - "integrity": "sha1-ysMo977kVzDUBLaSID/LWQ4XLV4=", - "dev": true, - "requires": { - "readable-stream": "2.3.3" - } - }, - "blob": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz", - "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE=", - "dev": true - }, - "bluebird": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", - "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=", - "dev": true - }, - "bn.js": { - "version": "4.11.7", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.7.tgz", - "integrity": "sha512-LxFiV5mefv0ley0SzqkOPR1bC4EbpPx8LkOz5vMe/Yi15t5hzwgO/G+tc7wOtL4PZTYjwHu8JnEiSLumuSjSfA==", - "dev": true - }, - "boom": { - "version": "2.10.1", - "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz", - "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=", - "dev": true, - "requires": { - "hoek": "2.16.3" - } - }, - "boxen": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.2.1.tgz", - "integrity": "sha1-DxHn/jRO25OXl3/BPt5/ZNlWSB0=", - "dev": true, - "requires": { - "ansi-align": "2.0.0", - "camelcase": "4.1.0", - "chalk": "2.0.1", - "cli-boxes": "1.0.0", - "string-width": "2.1.1", - "term-size": "1.2.0", - "widest-line": "1.0.0" - }, - "dependencies": { - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - } - } - }, - "brace-expansion": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz", - "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=", - "dev": true, - "requires": { - "balanced-match": "1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz", - "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=", - "dev": true, - "requires": { - "expand-range": "1.8.2", - "preserve": "0.2.0", - "repeat-element": "1.1.2" - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browserify-aes": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.0.6.tgz", - "integrity": "sha1-Xncl297x/Vkw1OurSFZ85FHEigo=", - "dev": true, - "requires": { - "buffer-xor": "1.0.3", - "cipher-base": "1.0.4", - "create-hash": "1.1.3", - "evp_bytestokey": "1.0.0", - "inherits": "2.0.3" - } - }, - "browserify-cipher": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz", - "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=", - "dev": true, - "requires": { - "browserify-aes": "1.0.6", - "browserify-des": "1.0.0", - "evp_bytestokey": "1.0.0" - } - }, - "browserify-des": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz", - "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=", - "dev": true, - "requires": { - "cipher-base": "1.0.4", - "des.js": "1.0.0", - "inherits": "2.0.3" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "4.11.7", - "randombytes": "2.0.5" - } - }, - "browserify-sign": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", - "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", - "dev": true, - "requires": { - "bn.js": "4.11.7", - "browserify-rsa": "4.0.1", - "create-hash": "1.1.3", - "create-hmac": "1.1.6", - "elliptic": "6.4.0", - "inherits": "2.0.3", - "parse-asn1": "5.1.0" - } - }, - "browserify-zlib": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.1.4.tgz", - "integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=", - "dev": true, - "requires": { - "pako": "0.2.9" - } - }, - "buf-compare": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/buf-compare/-/buf-compare-1.0.1.tgz", - "integrity": "sha1-/vKNqLgROgoNtEMLC2Rntpcws0o=", - "dev": true - }, - "buffer": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-3.6.0.tgz", - "integrity": "sha1-pyyTb3e5a/UvX357RnGAYoVR3vs=", - "dev": true, - "requires": { - "base64-js": "0.0.8", - "ieee754": "1.1.8", - "isarray": "1.0.0" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-modules": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", - "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "byline": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/byline/-/byline-5.0.0.tgz", - "integrity": "sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE=", - "dev": true - }, - "bytes": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.5.0.tgz", - "integrity": "sha1-TJQj6i0lLCcMQbK97+/5u2tiwGo=", - "dev": true - }, - "caching-transform": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-1.0.1.tgz", - "integrity": "sha1-bb2y8g+Nj7znnz6U6dF0Lc31wKE=", - "dev": true, - "requires": { - "md5-hex": "1.3.0", - "mkdirp": "0.5.1", - "write-file-atomic": "1.3.4" - }, - "dependencies": { - "md5-hex": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-1.3.0.tgz", - "integrity": "sha1-0sSv6YPENwZiF5uMrRRSGRNQRsQ=", - "dev": true, - "requires": { - "md5-o-matic": "0.1.1" - } - }, - "write-file-atomic": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-1.3.4.tgz", - "integrity": "sha1-+Aek8LHZ6ROuekgRLmzDrxmRtF8=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "imurmurhash": "0.1.4", - "slide": "1.1.6" - } - } - } - }, - "call-matcher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/call-matcher/-/call-matcher-1.0.1.tgz", - "integrity": "sha1-UTTQd5hPcSpU2tPL9i3ijc5BbKg=", - "dev": true, - "requires": { - "core-js": "2.4.1", - "deep-equal": "1.0.1", - "espurify": "1.7.0", - "estraverse": "4.2.0" - } - }, - "call-signature": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/call-signature/-/call-signature-0.0.2.tgz", - "integrity": "sha1-qEq8glpV70yysCi9dOIFpluaSZY=", - "dev": true - }, - "caller-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", - "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", - "dev": true, - "requires": { - "callsites": "0.2.0" - } - }, - "callsite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", - "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA=", - "dev": true - }, - "callsites": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", - "dev": true - }, - "camelcase": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", - "dev": true - }, - "camelcase-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", - "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", - "dev": true, - "requires": { - "camelcase": "2.1.1", - "map-obj": "1.0.1" - } - }, - "capture-stack-trace": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz", - "integrity": "sha1-Sm+gc5nCa7pH8LJJa00PtAjFVQ0=", - "dev": true - }, - "caseless": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", - "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", - "dev": true - }, - "caw": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/caw/-/caw-2.0.1.tgz", - "integrity": "sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA==", - "dev": true, - "requires": { - "get-proxy": "2.1.0", - "isurl": "1.0.0", - "tunnel-agent": "0.6.0", - "url-to-options": "1.0.1" - } - }, - "center-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz", - "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=", - "dev": true, - "requires": { - "align-text": "0.1.4", - "lazy-cache": "1.0.4" - } - }, - "chalk": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.0.1.tgz", - "integrity": "sha512-Mp+FXEI+FrwY/XYV45b2YD3E8i3HwnEAoFcM0qlZzq/RZ9RwWitt2Y/c7cqRAz70U7hfekqx6qNYthuKFO6K0g==", - "dev": true, - "requires": { - "ansi-styles": "3.2.0", - "escape-string-regexp": "1.0.5", - "supports-color": "4.2.1" - } - }, - "chokidar": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz", - "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=", - "dev": true, - "requires": { - "anymatch": "1.3.2", - "async-each": "1.0.1", - "fsevents": "1.1.2", - "glob-parent": "2.0.0", - "inherits": "2.0.3", - "is-binary-path": "1.0.1", - "is-glob": "2.0.1", - "path-is-absolute": "1.0.1", - "readdirp": "2.1.0" - } - }, - "ci-info": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.0.0.tgz", - "integrity": "sha1-3FKF8rTiUYIWg2gcOBwziPRuxTQ=", - "dev": true - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "2.0.3", - "safe-buffer": "5.1.1" - } - }, - "circular-json": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", - "dev": true - }, - "clean-stack": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-1.3.0.tgz", - "integrity": "sha1-noIVAa6XmYbEax1m0tQy2y/UrjE=", - "dev": true - }, - "clean-yaml-object": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/clean-yaml-object/-/clean-yaml-object-0.1.0.tgz", - "integrity": "sha1-Y/sRDcLOGoTcIfbZM0h20BCui2g=", - "dev": true - }, - "cli-boxes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", - "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=", - "dev": true - }, - "cli-cursor": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", - "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", - "dev": true, - "requires": { - "restore-cursor": "2.0.0" - } - }, - "cli-spinners": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-1.0.0.tgz", - "integrity": "sha1-75h+09SDkaw9q5GAtAanQhgNbmo=", - "dev": true - }, - "cli-truncate": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-1.1.0.tgz", - "integrity": "sha512-bAtZo0u82gCfaAGfSNxUdTI9mNyza7D8w4CVCcaOsy7sgwDzvx6ekr6cuWJqY3UGzgnQ1+4wgENup5eIhgxEYA==", - "dev": true, - "requires": { - "slice-ansi": "1.0.0", - "string-width": "2.1.1" - } - }, - "cli-width": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.1.0.tgz", - "integrity": "sha1-sjTKIJsp72b8UY2bmNWEewDt8Ao=", - "dev": true - }, - "clipboardy": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-1.1.4.tgz", - "integrity": "sha1-UbF1dPxoJYji3Slc+m5qoQnqte4=", - "dev": true, - "requires": { - "execa": "0.6.3" - }, - "dependencies": { - "execa": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.6.3.tgz", - "integrity": "sha1-V7aaWU8IF1nGnlNw8NF7nLEWWP4=", - "dev": true, - "requires": { - "cross-spawn": "5.1.0", - "get-stream": "3.0.0", - "is-stream": "1.1.0", - "npm-run-path": "2.0.2", - "p-finally": "1.0.0", - "signal-exit": "3.0.2", - "strip-eof": "1.0.0" - } - } - } - }, - "cliui": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz", - "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=", - "dev": true, - "requires": { - "center-align": "0.1.3", - "right-align": "0.1.3", - "wordwrap": "0.0.2" - }, - "dependencies": { - "wordwrap": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz", - "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=", - "dev": true - } - } - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true - }, - "co-with-promise": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co-with-promise/-/co-with-promise-4.6.0.tgz", - "integrity": "sha1-QT59tvWJOmC5Qs9JLEvsk9tBWrc=", - "dev": true, - "requires": { - "pinkie-promise": "1.0.0" - } - }, - "code-excerpt": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/code-excerpt/-/code-excerpt-2.1.0.tgz", - "integrity": "sha1-XcwIHoj0p+O1VOnjXX7yMtR/gUc=", - "dev": true, - "requires": { - "convert-to-spaces": "1.0.2" - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "color-convert": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz", - "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "combined-stream": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz", - "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=", - "dev": true, - "requires": { - "delayed-stream": "1.0.0" - } - }, - "commander": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", - "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", - "dev": true, - "requires": { - "graceful-readlink": "1.0.1" - } - }, - "common-path-prefix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-1.0.0.tgz", - "integrity": "sha1-zVL28HEuC6q5fW+XModPIvR3UsA=", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-bind": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", - "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E=", - "dev": true - }, - "component-emitter": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", - "dev": true - }, - "component-inherit": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz", - "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM=", - "dev": true - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concat-stream": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", - "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "readable-stream": "2.3.3", - "typedarray": "0.0.6" - } - }, - "concordance": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/concordance/-/concordance-3.0.0.tgz", - "integrity": "sha512-CZBzJ3/l5QJjlZM20WY7+5GP5pMTw+1UEbThcpMw8/rojsi5sBCiD8ZbBLtD+jYpRGAkwuKuqk108c154V9eyQ==", - "dev": true, - "requires": { - "date-time": "2.1.0", - "esutils": "2.0.2", - "fast-diff": "1.1.1", - "function-name-support": "0.2.0", - "js-string-escape": "1.0.1", - "lodash.clonedeep": "4.5.0", - "lodash.flattendeep": "4.4.0", - "lodash.merge": "4.6.0", - "md5-hex": "2.0.0", - "semver": "5.4.1", - "well-known-symbols": "1.0.0" - } - }, - "config-chain": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.11.tgz", - "integrity": "sha1-q6CXR9++TD5w52am5BWG4YWfxvI=", - "dev": true, - "requires": { - "ini": "1.3.4", - "proto-list": "1.2.4" - } - }, - "configstore": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.1.tgz", - "integrity": "sha512-5oNkD/L++l0O6xGXxb1EWS7SivtjfGQlRyxJsYgE0Z495/L81e2h4/d3r969hoPXuFItzNOKMtsXgYG4c7dYvw==", - "dev": true, - "requires": { - "dot-prop": "4.2.0", - "graceful-fs": "4.1.11", - "make-dir": "1.0.0", - "unique-string": "1.0.0", - "write-file-atomic": "2.1.0", - "xdg-basedir": "3.0.0" - } - }, - "console-browserify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", - "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", - "dev": true, - "requires": { - "date-now": "0.1.4" - } - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "contains-path": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", - "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", - "dev": true - }, - "content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=", - "dev": true - }, - "convert-source-map": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.0.tgz", - "integrity": "sha1-ms1whRxtXf3ZPZKC5e35SgP/RrU=", - "dev": true - }, - "convert-to-spaces": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/convert-to-spaces/-/convert-to-spaces-1.0.2.tgz", - "integrity": "sha1-fj5Iu+bZl7FBfdyihoIEtNPYVxU=", - "dev": true - }, - "core-assert": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/core-assert/-/core-assert-0.2.1.tgz", - "integrity": "sha1-+F4s+b/tKPdzzIs/pcW2m9wC/j8=", - "dev": true, - "requires": { - "buf-compare": "1.0.1", - "is-error": "2.2.1" - } - }, - "core-js": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.4.1.tgz", - "integrity": "sha1-TekR5mew6ukSTjQlS1OupvxhjT4=", - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "cosmiconfig": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-1.1.0.tgz", - "integrity": "sha1-DeoPmATv37kp+7GxiOJVU+oFPTc=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "js-yaml": "3.9.0", - "minimist": "1.2.0", - "object-assign": "4.1.1", - "os-homedir": "1.0.2", - "parse-json": "2.2.0", - "pinkie-promise": "2.0.1", - "require-from-string": "1.2.1" - }, - "dependencies": { - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "2.0.4" - } - } - } - }, - "create-ecdh": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz", - "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=", - "dev": true, - "requires": { - "bn.js": "4.11.7", - "elliptic": "6.4.0" - } - }, - "create-error-class": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/create-error-class/-/create-error-class-3.0.2.tgz", - "integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=", - "dev": true, - "requires": { - "capture-stack-trace": "1.0.0" - } - }, - "create-hash": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz", - "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=", - "dev": true, - "requires": { - "cipher-base": "1.0.4", - "inherits": "2.0.3", - "ripemd160": "2.0.1", - "sha.js": "2.4.8" - } - }, - "create-hmac": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz", - "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=", - "dev": true, - "requires": { - "cipher-base": "1.0.4", - "create-hash": "1.1.3", - "inherits": "2.0.3", - "ripemd160": "2.0.1", - "safe-buffer": "5.1.1", - "sha.js": "2.4.8" - } - }, - "credit-card": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/credit-card/-/credit-card-3.0.1.tgz", - "integrity": "sha1-uY842UrfMnXxQJHYvSzRQcx4nFY=", - "dev": true, - "requires": { - "lodash.merge": "4.6.0", - "reach": "1.0.0" - } - }, - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "4.1.1", - "shebang-command": "1.2.0", - "which": "1.3.0" - } - }, - "cryptiles": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz", - "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=", - "dev": true, - "requires": { - "boom": "2.10.1" - } - }, - "crypto-browserify": { - "version": "3.11.1", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.11.1.tgz", - "integrity": "sha512-Na7ZlwCOqoaW5RwUK1WpXws2kv8mNhWdTlzob0UXulk6G9BDbyiJaGTYBIX61Ozn9l1EPPJpICZb4DaOpT9NlQ==", - "dev": true, - "requires": { - "browserify-cipher": "1.0.0", - "browserify-sign": "4.0.4", - "create-ecdh": "4.0.0", - "create-hash": "1.1.3", - "create-hmac": "1.1.6", - "diffie-hellman": "5.0.2", - "inherits": "2.0.3", - "pbkdf2": "3.0.12", - "public-encrypt": "4.0.0", - "randombytes": "2.0.5" - } - }, - "crypto-random-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-1.0.0.tgz", - "integrity": "sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4=", - "dev": true - }, - "currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", - "dev": true, - "requires": { - "array-find-index": "1.0.2" - } - }, - "d": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", - "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", - "dev": true, - "requires": { - "es5-ext": "0.10.24" - } - }, - "dashdash": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", - "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=", - "dev": true, - "requires": { - "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } - } - }, - "date-fns": { - "version": "1.28.5", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.28.5.tgz", - "integrity": "sha1-JXz8RdMi30XvVlhmWWfuhBzXP68=", - "dev": true - }, - "date-now": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", - "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", - "dev": true - }, - "date-time": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/date-time/-/date-time-2.1.0.tgz", - "integrity": "sha512-/9+C44X7lot0IeiyfgJmETtRMhBidBYM2QFFIkGa0U1k+hSyY87Nw7PY3eDqpvCBm7I3WCSfPeZskW/YYq6m4g==", - "dev": true, - "requires": { - "time-zone": "1.0.0" - } - }, - "dateformat": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.0.0.tgz", - "integrity": "sha1-J0Pjq7XD/CRi5SfcpEXgTp9N7hc=", - "dev": true - }, - "death": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/death/-/death-1.1.0.tgz", - "integrity": "sha1-AaqcQB7dknUFFEcLgmY5DGbGcxg=", - "dev": true - }, - "debug": { - "version": "2.6.8", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz", - "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decompress": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.0.tgz", - "integrity": "sha1-eu3YVCflqS2s/lVnSnxQXpbQH50=", - "dev": true, - "requires": { - "decompress-tar": "4.1.1", - "decompress-tarbz2": "4.1.0", - "decompress-targz": "4.1.1", - "decompress-unzip": "4.0.1", - "graceful-fs": "4.1.11", - "make-dir": "1.0.0", - "pify": "2.3.0", - "strip-dirs": "2.0.0" - } - }, - "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=", - "dev": true, - "requires": { - "mimic-response": "1.0.0" - } - }, - "decompress-tar": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", - "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", - "dev": true, - "requires": { - "file-type": "5.2.0", - "is-stream": "1.1.0", - "tar-stream": "1.5.4" - } - }, - "decompress-tarbz2": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.0.tgz", - "integrity": "sha1-+6tY1d5z8/0hPKw68cGDNPUcuJE=", - "dev": true, - "requires": { - "decompress-tar": "4.1.1", - "file-type": "3.9.0", - "is-stream": "1.1.0", - "pify": "2.3.0", - "seek-bzip": "1.0.5", - "unbzip2-stream": "1.2.5" - }, - "dependencies": { - "file-type": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", - "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=", - "dev": true - } - } - }, - "decompress-targz": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", - "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", - "dev": true, - "requires": { - "decompress-tar": "4.1.1", - "file-type": "5.2.0", - "is-stream": "1.1.0" - } - }, - "decompress-unzip": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", - "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=", - "dev": true, - "requires": { - "file-type": "3.9.0", - "get-stream": "2.3.1", - "pify": "2.3.0", - "yauzl": "2.8.0" - }, - "dependencies": { - "file-type": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", - "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=", - "dev": true - }, - "get-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", - "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", - "dev": true, - "requires": { - "object-assign": "4.1.1", - "pinkie-promise": "2.0.1" - } - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "2.0.4" - } - } - } - }, - "deep-assign": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/deep-assign/-/deep-assign-1.0.0.tgz", - "integrity": "sha1-sJJ0O+hCfcYh6gBnzex+cN0Z83s=", - "dev": true, - "requires": { - "is-obj": "1.0.1" - } - }, - "deep-equal": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", - "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=", - "dev": true - }, - "deep-extend": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz", - "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8=", - "dev": true - }, - "deep-is": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true - }, - "deep-strict-equal": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/deep-strict-equal/-/deep-strict-equal-0.2.0.tgz", - "integrity": "sha1-SgeBR6irV/ag1PVUckPNIvROtOQ=", - "dev": true, - "requires": { - "core-assert": "0.2.1" - } - }, - "del": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", - "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", - "dev": true, - "requires": { - "globby": "5.0.0", - "is-path-cwd": "1.0.0", - "is-path-in-cwd": "1.0.0", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "rimraf": "2.6.1" - }, - "dependencies": { - "globby": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", - "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", - "dev": true, - "requires": { - "array-union": "1.0.2", - "arrify": "1.0.1", - "glob": "7.1.2", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" - } - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "2.0.4" - } - } - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "dev": true - }, - "deployment-type": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/deployment-type/-/deployment-type-1.0.1.tgz", - "integrity": "sha1-X0fjOL9dLNJqvulxxgxYTqSvm8E=", - "dev": true, - "requires": { - "fs-extra": "3.0.1", - "path-exists": "3.0.0", - "path-type": "2.0.0" - }, - "dependencies": { - "fs-extra": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz", - "integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "jsonfile": "3.0.1", - "universalify": "0.1.1" - } - } - } - }, - "des.js": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", - "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "minimalistic-assert": "1.0.0" - } - }, - "detect-indent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", - "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", - "dev": true, - "requires": { - "repeating": "2.0.1" - } - }, - "diffie-hellman": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz", - "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=", - "dev": true, - "requires": { - "bn.js": "4.11.7", - "miller-rabin": "4.0.0", - "randombytes": "2.0.5" - } - }, - "docker-file-parser": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/docker-file-parser/-/docker-file-parser-1.0.2.tgz", - "integrity": "sha1-sMY9GM7uKsXVOFlo0Hf+q4jDfiY=", - "dev": true - }, - "doctrine": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz", - "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=", - "dev": true, - "requires": { - "esutils": "2.0.2", - "isarray": "1.0.0" - } - }, - "domain-browser": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz", - "integrity": "sha1-hnqksJP6oF8d4IwG9NeyH9+GmLw=", - "dev": true - }, - "dot-prop": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", - "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", - "dev": true, - "requires": { - "is-obj": "1.0.1" - } - }, - "dotenv": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-4.0.0.tgz", - "integrity": "sha1-hk7xN5rO1Vzm+V3r7NzhefegzR0=", - "dev": true - }, - "download": { - "version": "6.2.5", - "resolved": "https://registry.npmjs.org/download/-/download-6.2.5.tgz", - "integrity": "sha512-DpO9K1sXAST8Cpzb7kmEhogJxymyVUd5qz/vCOSyvwtp2Klj2XcDt5YUuasgxka44SxF0q5RriKIwJmQHG2AuA==", - "dev": true, - "requires": { - "caw": "2.0.1", - "content-disposition": "0.5.2", - "decompress": "4.2.0", - "ext-name": "5.0.0", - "file-type": "5.2.0", - "filenamify": "2.0.0", - "get-stream": "3.0.0", - "got": "7.1.0", - "make-dir": "1.0.0", - "p-event": "1.3.0", - "pify": "3.0.0" - }, - "dependencies": { - "got": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/got/-/got-7.1.0.tgz", - "integrity": "sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw==", - "dev": true, - "requires": { - "decompress-response": "3.3.0", - "duplexer3": "0.1.4", - "get-stream": "3.0.0", - "is-plain-obj": "1.1.0", - "is-retry-allowed": "1.1.0", - "is-stream": "1.1.0", - "isurl": "1.0.0", - "lowercase-keys": "1.0.0", - "p-cancelable": "0.3.0", - "p-timeout": "1.2.0", - "safe-buffer": "5.1.1", - "timed-out": "4.0.1", - "url-parse-lax": "1.0.0", - "url-to-options": "1.0.1" - } - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "duplexer3": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", - "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", - "dev": true - }, - "ecc-jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", - "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", - "dev": true, - "optional": true, - "requires": { - "jsbn": "0.1.1" - } - }, - "elegant-spinner": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/elegant-spinner/-/elegant-spinner-1.0.1.tgz", - "integrity": "sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4=", - "dev": true - }, - "elliptic": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", - "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", - "dev": true, - "requires": { - "bn.js": "4.11.7", - "brorand": "1.1.0", - "hash.js": "1.1.3", - "hmac-drbg": "1.0.1", - "inherits": "2.0.3", - "minimalistic-assert": "1.0.0", - "minimalistic-crypto-utils": "1.0.1" - } - }, - "email-prompt": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/email-prompt/-/email-prompt-0.3.1.tgz", - "integrity": "sha1-YvD+mRSnOIiXq0K1QJ3Q83sIbAY=", - "dev": true, - "requires": { - "ansi-escapes": "2.0.0", - "chalk": "1.1.3" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "email-validator": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/email-validator/-/email-validator-1.0.7.tgz", - "integrity": "sha1-RiHKMvx0HrgzrJjV+1VnC34FbJU=", - "dev": true - }, - "emojis-list": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", - "dev": true - }, - "empower-core": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/empower-core/-/empower-core-0.6.2.tgz", - "integrity": "sha1-Wt71ZgiOMfuoC6CjbfR9cJQWkUQ=", - "dev": true, - "requires": { - "call-signature": "0.0.2", - "core-js": "2.4.1" - } - }, - "encoding": { - "version": "0.1.12", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", - "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", - "dev": true, - "requires": { - "iconv-lite": "0.4.18" - } - }, - "end-of-stream": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz", - "integrity": "sha1-epDYM+/abPpurA9JSduw+tOmMgY=", - "dev": true, - "requires": { - "once": "1.4.0" - } - }, - "engine.io-client": { - "version": "1.8.4", - "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-1.8.4.tgz", - "integrity": "sha1-n+hd7iWFPKa6viW9KtaHEIY+kcI=", - "dev": true, - "requires": { - "component-emitter": "1.2.1", - "component-inherit": "0.0.3", - "debug": "2.3.3", - "engine.io-parser": "1.3.2", - "has-cors": "1.1.0", - "indexof": "0.0.1", - "parsejson": "0.0.3", - "parseqs": "0.0.5", - "parseuri": "0.0.5", - "ws": "1.1.2", - "xmlhttprequest-ssl": "1.5.3", - "yeast": "0.1.2" - }, - "dependencies": { - "debug": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", - "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", - "dev": true, - "requires": { - "ms": "0.7.2" - } - }, - "ms": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", - "dev": true - } - } - }, - "engine.io-parser": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-1.3.2.tgz", - "integrity": "sha1-k3sHnwAH0Ik+xW1GyyILjLQ1Igo=", - "dev": true, - "requires": { - "after": "0.8.2", - "arraybuffer.slice": "0.0.6", - "base64-arraybuffer": "0.1.5", - "blob": "0.0.4", - "has-binary": "0.1.7", - "wtf-8": "1.0.0" - } - }, - "enhance-visitors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/enhance-visitors/-/enhance-visitors-1.0.0.tgz", - "integrity": "sha1-qpRdBdpGVnKh69OP7i7T2oUY6Vo=", - "dev": true, - "requires": { - "lodash": "4.17.4" - } - }, - "enhanced-resolve": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-3.4.1.tgz", - "integrity": "sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "memory-fs": "0.4.1", - "object-assign": "4.1.1", - "tapable": "0.2.7" - } - }, - "epipebomb": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/epipebomb/-/epipebomb-1.0.0.tgz", - "integrity": "sha1-V9He2h1ryBYisRinX+a1p9NPbYg=", - "dev": true - }, - "equal-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/equal-length/-/equal-length-1.0.1.tgz", - "integrity": "sha1-IcoRLUirJLTh5//A5TOdMf38J0w=", - "dev": true - }, - "errno": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.4.tgz", - "integrity": "sha1-uJbiOp5ei6M4cfyZar02NfyaHH0=", - "dev": true, - "requires": { - "prr": "0.0.0" - } - }, - "error-ex": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", - "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", - "dev": true, - "requires": { - "is-arrayish": "0.2.1" - } - }, - "es5-ext": { - "version": "0.10.24", - "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.24.tgz", - "integrity": "sha1-pVh3yZJLwMjZvTwsvhdJWsFwmxQ=", - "dev": true, - "requires": { - "es6-iterator": "2.0.1", - "es6-symbol": "3.1.1" - } - }, - "es6-error": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.0.2.tgz", - "integrity": "sha1-7sXHJurO9Rt/a3PCDbbhsTsGnJg=", - "dev": true - }, - "es6-iterator": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz", - "integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=", - "dev": true, - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.24", - "es6-symbol": "3.1.1" - } - }, - "es6-map": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz", - "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=", - "dev": true, - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.24", - "es6-iterator": "2.0.1", - "es6-set": "0.1.5", - "es6-symbol": "3.1.1", - "event-emitter": "0.3.5" - } - }, - "es6-set": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz", - "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=", - "dev": true, - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.24", - "es6-iterator": "2.0.1", - "es6-symbol": "3.1.1", - "event-emitter": "0.3.5" - } - }, - "es6-symbol": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz", - "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=", - "dev": true, - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.24" - } - }, - "es6-weak-map": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz", - "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=", - "dev": true, - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.24", - "es6-iterator": "2.0.1", - "es6-symbol": "3.1.1" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", - "dev": true - }, - "escodegen": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.8.1.tgz", - "integrity": "sha1-WltTr0aTEQvrsIZ6o0MN07cKEBg=", - "dev": true, - "requires": { - "esprima": "2.7.3", - "estraverse": "1.9.3", - "esutils": "2.0.2", - "optionator": "0.8.2", - "source-map": "0.2.0" - }, - "dependencies": { - "esprima": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", - "dev": true - }, - "estraverse": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-1.9.3.tgz", - "integrity": "sha1-r2fy3JIlgkFZUJJgkaQAXSnJu0Q=", - "dev": true - }, - "source-map": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.2.0.tgz", - "integrity": "sha1-2rc/vPwrqBm03gO9b26qSBZLP50=", - "dev": true, - "optional": true, - "requires": { - "amdefine": "1.0.1" - } - } - } - }, - "escope": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz", - "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=", - "dev": true, - "requires": { - "es6-map": "0.1.5", - "es6-weak-map": "2.0.2", - "esrecurse": "4.2.0", - "estraverse": "4.2.0" - } - }, - "eslint": { - "version": "3.19.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-3.19.0.tgz", - "integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=", - "dev": true, - "requires": { - "babel-code-frame": "6.22.0", - "chalk": "1.1.3", - "concat-stream": "1.6.0", - "debug": "2.6.8", - "doctrine": "2.0.0", - "escope": "3.6.0", - "espree": "3.4.3", - "esquery": "1.0.0", - "estraverse": "4.2.0", - "esutils": "2.0.2", - "file-entry-cache": "2.0.0", - "glob": "7.1.2", - "globals": "9.18.0", - "ignore": "3.3.3", - "imurmurhash": "0.1.4", - "inquirer": "0.12.0", - "is-my-json-valid": "2.16.0", - "is-resolvable": "1.0.0", - "js-yaml": "3.9.0", - "json-stable-stringify": "1.0.1", - "levn": "0.3.0", - "lodash": "4.17.4", - "mkdirp": "0.5.1", - "natural-compare": "1.4.0", - "optionator": "0.8.2", - "path-is-inside": "1.0.2", - "pluralize": "1.2.1", - "progress": "1.1.8", - "require-uncached": "1.0.3", - "shelljs": "0.7.8", - "strip-bom": "3.0.0", - "strip-json-comments": "2.0.1", - "table": "3.8.3", - "text-table": "0.2.0", - "user-home": "2.0.0" - }, - "dependencies": { - "ansi-escapes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, - "cli-cursor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", - "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", - "dev": true, - "requires": { - "restore-cursor": "1.0.1" - } - }, - "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", - "dev": true, - "requires": { - "escape-string-regexp": "1.0.5", - "object-assign": "4.1.1" - } - }, - "inquirer": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz", - "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=", - "dev": true, - "requires": { - "ansi-escapes": "1.4.0", - "ansi-regex": "2.1.1", - "chalk": "1.1.3", - "cli-cursor": "1.0.2", - "cli-width": "2.1.0", - "figures": "1.7.0", - "lodash": "4.17.4", - "readline2": "1.0.1", - "run-async": "0.1.0", - "rx-lite": "3.1.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "through": "2.3.8" - } - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, - "onetime": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", - "dev": true - }, - "progress": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", - "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", - "dev": true - }, - "restore-cursor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", - "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", - "dev": true, - "requires": { - "exit-hook": "1.1.1", - "onetime": "1.1.0" - } - }, - "run-async": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz", - "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=", - "dev": true, - "requires": { - "once": "1.4.0" - } - }, - "rx-lite": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz", - "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=", - "dev": true - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "eslint-config-prettier": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-2.3.0.tgz", - "integrity": "sha1-t1seq+oMi5ezRANkfuJds0m52KA=", - "dev": true, - "requires": { - "get-stdin": "5.0.1" - }, - "dependencies": { - "get-stdin": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", - "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=", - "dev": true - } - } - }, - "eslint-config-xo": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/eslint-config-xo/-/eslint-config-xo-0.18.2.tgz", - "integrity": "sha1-ChVxIIdWGZKec1/9axhcQeihh68=", - "dev": true - }, - "eslint-formatter-pretty": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eslint-formatter-pretty/-/eslint-formatter-pretty-1.1.0.tgz", - "integrity": "sha1-q00G2gL+2ME66fDcVApDPvftb14=", - "dev": true, - "requires": { - "ansi-escapes": "1.4.0", - "chalk": "1.1.3", - "log-symbols": "1.0.2", - "plur": "2.1.2", - "string-width": "2.1.1" - }, - "dependencies": { - "ansi-escapes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "eslint-import-resolver-node": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.1.tgz", - "integrity": "sha512-yUtXS15gIcij68NmXmP9Ni77AQuCN0itXbCc/jWd8C6/yKZaSNXicpC8cgvjnxVdmfsosIXrjpzFq7GcDryb6A==", - "dev": true, - "requires": { - "debug": "2.6.8", - "resolve": "1.4.0" - } - }, - "eslint-module-utils": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz", - "integrity": "sha512-jDI/X5l/6D1rRD/3T43q8Qgbls2nq5km5KSqiwlyUbGo5+04fXhMKdCPhjwbqAa6HXWaMxj8Q4hQDIh7IadJQw==", - "dev": true, - "requires": { - "debug": "2.6.8", - "pkg-dir": "1.0.0" - }, - "dependencies": { - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "2.1.0", - "pinkie-promise": "2.0.1" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "2.0.1" - } - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "2.0.4" - } - }, - "pkg-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-1.0.0.tgz", - "integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=", - "dev": true, - "requires": { - "find-up": "1.1.2" - } - } - } - }, - "eslint-plugin-ava": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-ava/-/eslint-plugin-ava-4.2.1.tgz", - "integrity": "sha1-fNtegbx3n0gz1HIKYJPl9KbKGRM=", - "dev": true, - "requires": { - "arrify": "1.0.1", - "deep-strict-equal": "0.2.0", - "enhance-visitors": "1.0.0", - "espree": "3.4.3", - "espurify": "1.7.0", - "import-modules": "1.1.0", - "multimatch": "2.1.0", - "pkg-up": "2.0.0" - } - }, - "eslint-plugin-import": { - "version": "2.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.7.0.tgz", - "integrity": "sha512-HGYmpU9f/zJaQiKNQOVfHUh2oLWW3STBrCgH0sHTX1xtsxYlH1zjLh8FlQGEIdZSdTbUMaV36WaZ6ImXkenGxQ==", - "dev": true, - "requires": { - "builtin-modules": "1.1.1", - "contains-path": "0.1.0", - "debug": "2.6.8", - "doctrine": "1.5.0", - "eslint-import-resolver-node": "0.3.1", - "eslint-module-utils": "2.1.1", - "has": "1.0.1", - "lodash.cond": "4.5.2", - "minimatch": "3.0.4", - "read-pkg-up": "2.0.0" - }, - "dependencies": { - "doctrine": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", - "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", - "dev": true, - "requires": { - "esutils": "2.0.2", - "isarray": "1.0.0" - } - } - } - }, - "eslint-plugin-no-use-extend-native": { - "version": "0.3.12", - "resolved": "https://registry.npmjs.org/eslint-plugin-no-use-extend-native/-/eslint-plugin-no-use-extend-native-0.3.12.tgz", - "integrity": "sha1-OtmgDC3yO11/f2vpFVCYWkq3Aeo=", - "dev": true, - "requires": { - "is-get-set-prop": "1.0.0", - "is-js-type": "2.0.0", - "is-obj-prop": "1.0.0", - "is-proto-prop": "1.0.0" - } - }, - "eslint-plugin-promise": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.5.0.tgz", - "integrity": "sha1-ePu2/+BHIBYnVp6FpsU3OvKmj8o=", - "dev": true - }, - "eslint-plugin-unicorn": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-2.1.2.tgz", - "integrity": "sha1-md/+n0dzsEvDk1an/r1k3XACdLw=", - "dev": true, - "requires": { - "import-modules": "1.1.0", - "lodash.camelcase": "4.3.0", - "lodash.kebabcase": "4.1.1", - "lodash.snakecase": "4.1.1", - "lodash.upperfirst": "4.3.1" - } - }, - "espower-location-detector": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/espower-location-detector/-/espower-location-detector-1.0.0.tgz", - "integrity": "sha1-oXt+zFnTDheeK+9z+0E3cEyzMbU=", - "dev": true, - "requires": { - "is-url": "1.2.2", - "path-is-absolute": "1.0.1", - "source-map": "0.5.6", - "xtend": "4.0.1" - } - }, - "espree": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/espree/-/espree-3.4.3.tgz", - "integrity": "sha1-KRC1zNSc6JPC//+qtP2LOjG4I3Q=", - "dev": true, - "requires": { - "acorn": "5.1.1", - "acorn-jsx": "3.0.1" - } - }, - "esprima": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", - "dev": true - }, - "espurify": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/espurify/-/espurify-1.7.0.tgz", - "integrity": "sha1-HFz2y8zDLm9jk4C9T5kfq5up0iY=", - "dev": true, - "requires": { - "core-js": "2.4.1" - } - }, - "esquery": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", - "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", - "dev": true, - "requires": { - "estraverse": "4.2.0" - } - }, - "esrecurse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz", - "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=", - "dev": true, - "requires": { - "estraverse": "4.2.0", - "object-assign": "4.1.1" - } - }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", - "dev": true - }, - "event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=", - "dev": true, - "requires": { - "d": "1.0.0", - "es5-ext": "0.10.24" - } - }, - "events": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/events/-/events-1.1.1.tgz", - "integrity": "sha1-nr23Y1rQmccNzEwqH1AEKI6L2SQ=", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.0.tgz", - "integrity": "sha1-SXtmrZ/vZc18CKYYCCS6FHa2blM=", - "dev": true, - "requires": { - "create-hash": "1.1.3" - } - }, - "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", - "dev": true, - "requires": { - "cross-spawn": "5.1.0", - "get-stream": "3.0.0", - "is-stream": "1.1.0", - "npm-run-path": "2.0.2", - "p-finally": "1.0.0", - "signal-exit": "3.0.2", - "strip-eof": "1.0.0" - } - }, - "exit-hook": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", - "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", - "dev": true - }, - "expand-brackets": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz", - "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=", - "dev": true, - "requires": { - "is-posix-bracket": "0.1.1" - } - }, - "expand-range": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/expand-range/-/expand-range-1.8.2.tgz", - "integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=", - "dev": true, - "requires": { - "fill-range": "2.2.3" - } - }, - "expand-template": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-1.0.3.tgz", - "integrity": "sha1-bDAzIxd6YrGyLAcCefeGEoe2mxo=", - "dev": true - }, - "ext-list": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz", - "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==", - "dev": true, - "requires": { - "mime-db": "1.29.0" - } - }, - "ext-name": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz", - "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==", - "dev": true, - "requires": { - "ext-list": "2.2.2", - "sort-keys-length": "1.0.1" - } - }, - "extend": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", - "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", - "dev": true - }, - "external-editor": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.0.4.tgz", - "integrity": "sha1-HtkZnanL/i7y96MbL96LDRI2iXI=", - "dev": true, - "requires": { - "iconv-lite": "0.4.18", - "jschardet": "1.5.0", - "tmp": "0.0.31" - } - }, - "extglob": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz", - "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=", - "dev": true, - "requires": { - "is-extglob": "1.0.0" - } - }, - "extsprintf": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.0.2.tgz", - "integrity": "sha1-4QgOBljjALBilJkMxw4VAiNf1VA=", - "dev": true - }, - "fast-deep-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz", - "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8=", - "dev": true - }, - "fast-diff": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.1.1.tgz", - "integrity": "sha1-CuoOTmBbaiGJ8Ok21Lf7rxt8/Zs=", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "fd-slicer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", - "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", - "dev": true, - "requires": { - "pend": "1.2.0" - } - }, - "figures": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", - "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", - "dev": true, - "requires": { - "escape-string-regexp": "1.0.5" - } - }, - "file-entry-cache": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", - "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", - "dev": true, - "requires": { - "flat-cache": "1.2.2", - "object-assign": "4.1.1" - } - }, - "file-type": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-5.2.0.tgz", - "integrity": "sha1-LdvqfHP/42No365J3DOMBYwritY=", - "dev": true - }, - "filename-regex": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", - "integrity": "sha1-wcS5vuPglyXdsQa3XB4wH+LxiyY=", - "dev": true - }, - "filename-reserved-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz", - "integrity": "sha1-q/c9+rc10EVECr/qLZHzieu/oik=", - "dev": true - }, - "filenamify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-2.0.0.tgz", - "integrity": "sha1-vRYiYsC26Uv7zc8Zo7uzdk94VpU=", - "dev": true, - "requires": { - "filename-reserved-regex": "2.0.0", - "strip-outer": "1.0.0", - "trim-repeated": "1.0.0" - } - }, - "fill-range": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz", - "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=", - "dev": true, - "requires": { - "is-number": "2.1.0", - "isobject": "2.1.0", - "randomatic": "1.1.7", - "repeat-element": "1.1.2", - "repeat-string": "1.6.1" - } - }, - "find-cache-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz", - "integrity": "sha1-kojj6ePMN0hxfTnq3hfPcfww7m8=", - "dev": true, - "requires": { - "commondir": "1.0.1", - "make-dir": "1.0.0", - "pkg-dir": "2.0.0" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "2.0.0" - } - }, - "flat-cache": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.2.2.tgz", - "integrity": "sha1-+oZxTnLCHbiGAXYezy9VXRq8a5Y=", - "dev": true, - "requires": { - "circular-json": "0.3.3", - "del": "2.2.2", - "graceful-fs": "4.1.11", - "write": "0.2.1" - } - }, - "fn-name": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fn-name/-/fn-name-2.0.1.tgz", - "integrity": "sha1-UhTXU3pNBqSjAcDMJi/rhBiAAuc=", - "dev": true - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "for-own": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz", - "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=", - "dev": true, - "requires": { - "for-in": "1.0.2" - } - }, - "forever-agent": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", - "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", - "dev": true - }, - "form-data": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz", - "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=", - "dev": true, - "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.16" - } - }, - "fs-extra": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.0.tgz", - "integrity": "sha1-QU+0yi0hcLoAFBWdOorsMwNBjZ4=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "jsonfile": "3.0.1", - "universalify": "0.1.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.2.tgz", - "integrity": "sha512-Sn44E5wQW4bTHXvQmvSHwqbuiXtduD6Rrjm2ZtUEGbyrig+nUH3t/QD4M4/ZXViY556TBpRgZkHLDx3JxPwxiw==", - "dev": true, - "optional": true, - "requires": { - "nan": "2.6.2", - "node-pre-gyp": "0.6.36" - }, - "dependencies": { - "abbrev": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "ajv": { - "version": "4.11.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "co": "4.6.0", - "json-stable-stringify": "1.0.1" - } - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true - }, - "aproba": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "1.0.0", - "readable-stream": "2.2.9" - } - }, - "asn1": { - "version": "0.2.3", - "bundled": true, - "dev": true, - "optional": true - }, - "assert-plus": { - "version": "0.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "asynckit": { - "version": "0.4.0", - "bundled": true, - "dev": true, - "optional": true - }, - "aws-sign2": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "aws4": { - "version": "1.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "balanced-match": { - "version": "0.4.2", - "bundled": true, - "dev": true - }, - "bcrypt-pbkdf": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "tweetnacl": "0.14.5" - } - }, - "block-stream": { - "version": "0.0.9", - "bundled": true, - "dev": true, - "requires": { - "inherits": "2.0.3" - } - }, - "boom": { - "version": "2.10.1", - "bundled": true, - "dev": true, - "requires": { - "hoek": "2.16.3" - } - }, - "brace-expansion": { - "version": "1.1.7", - "bundled": true, - "dev": true, - "requires": { - "balanced-match": "0.4.2", - "concat-map": "0.0.1" - } - }, - "buffer-shims": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "caseless": { - "version": "0.12.0", - "bundled": true, - "dev": true, - "optional": true - }, - "co": { - "version": "4.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "combined-stream": { - "version": "1.0.5", - "bundled": true, - "dev": true, - "requires": { - "delayed-stream": "1.0.0" - } - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "cryptiles": { - "version": "2.0.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "boom": "2.10.1" - } - }, - "dashdash": { - "version": "1.14.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "debug": { - "version": "2.6.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "deep-extend": { - "version": "0.4.2", - "bundled": true, - "dev": true, - "optional": true - }, - "delayed-stream": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "ecc-jsbn": { - "version": "0.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "jsbn": "0.1.1" - } - }, - "extend": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "extsprintf": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "forever-agent": { - "version": "0.6.1", - "bundled": true, - "dev": true, - "optional": true - }, - "form-data": { - "version": "2.1.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "asynckit": "0.4.0", - "combined-stream": "1.0.5", - "mime-types": "2.1.15" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "fstream": { - "version": "1.0.11", - "bundled": true, - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "inherits": "2.0.3", - "mkdirp": "0.5.1", - "rimraf": "2.6.1" - } - }, - "fstream-ignore": { - "version": "1.0.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "fstream": "1.0.11", - "inherits": "2.0.3", - "minimatch": "3.0.4" - } - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "1.1.1", - "console-control-strings": "1.1.0", - "has-unicode": "2.0.1", - "object-assign": "4.1.1", - "signal-exit": "3.0.2", - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wide-align": "1.1.2" - } - }, - "getpass": { - "version": "0.1.7", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "glob": { - "version": "7.1.2", - "bundled": true, - "dev": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "graceful-fs": { - "version": "4.1.11", - "bundled": true, - "dev": true - }, - "har-schema": { - "version": "1.0.5", - "bundled": true, - "dev": true, - "optional": true - }, - "har-validator": { - "version": "4.2.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ajv": "4.11.8", - "har-schema": "1.0.5" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "hawk": { - "version": "3.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "boom": "2.10.1", - "cryptiles": "2.0.5", - "hoek": "2.16.3", - "sntp": "1.0.9" - } - }, - "hoek": { - "version": "2.16.3", - "bundled": true, - "dev": true - }, - "http-signature": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "assert-plus": "0.2.0", - "jsprim": "1.4.0", - "sshpk": "1.13.0" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true - }, - "ini": { - "version": "1.3.4", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, - "is-typedarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true - }, - "isstream": { - "version": "0.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "jodid25519": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "jsbn": "0.1.1" - } - }, - "jsbn": { - "version": "0.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "json-schema": { - "version": "0.2.3", - "bundled": true, - "dev": true, - "optional": true - }, - "json-stable-stringify": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "jsonify": "0.0.0" - } - }, - "json-stringify-safe": { - "version": "5.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "jsonify": { - "version": "0.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "jsprim": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.0.2", - "json-schema": "0.2.3", - "verror": "1.3.6" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "mime-db": { - "version": "1.27.0", - "bundled": true, - "dev": true - }, - "mime-types": { - "version": "2.1.15", - "bundled": true, - "dev": true, - "requires": { - "mime-db": "1.27.0" - } - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "requires": { - "brace-expansion": "1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "node-pre-gyp": { - "version": "0.6.36", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "mkdirp": "0.5.1", - "nopt": "4.0.1", - "npmlog": "4.1.0", - "rc": "1.2.1", - "request": "2.81.0", - "rimraf": "2.6.1", - "semver": "5.3.0", - "tar": "2.2.1", - "tar-pack": "3.4.0" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1.1.0", - "osenv": "0.1.4" - } - }, - "npmlog": { - "version": "4.1.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "1.1.4", - "console-control-strings": "1.1.0", - "gauge": "2.7.4", - "set-blocking": "2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "oauth-sign": { - "version": "0.8.2", - "bundled": true, - "dev": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "requires": { - "wrappy": "1.0.2" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true - }, - "performance-now": { - "version": "0.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "1.0.7", - "bundled": true, - "dev": true - }, - "punycode": { - "version": "1.4.1", - "bundled": true, - "dev": true, - "optional": true - }, - "qs": { - "version": "6.4.0", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "0.4.2", - "ini": "1.3.4", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.2.9", - "bundled": true, - "dev": true, - "requires": { - "buffer-shims": "1.0.0", - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "string_decoder": "1.0.1", - "util-deprecate": "1.0.2" - } - }, - "request": { - "version": "2.81.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aws-sign2": "0.6.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.1.4", - "har-validator": "4.2.1", - "hawk": "3.1.3", - "http-signature": "1.1.1", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.15", - "oauth-sign": "0.8.2", - "performance-now": "0.2.0", - "qs": "6.4.0", - "safe-buffer": "5.0.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.2", - "tunnel-agent": "0.6.0", - "uuid": "3.0.1" - } - }, - "rimraf": { - "version": "2.6.1", - "bundled": true, - "dev": true, - "requires": { - "glob": "7.1.2" - } - }, - "safe-buffer": { - "version": "5.0.1", - "bundled": true, - "dev": true - }, - "semver": { - "version": "5.3.0", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sntp": { - "version": "1.0.9", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "hoek": "2.16.3" - } - }, - "sshpk": { - "version": "1.13.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "asn1": "0.2.3", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.1", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.1", - "getpass": "0.1.7", - "jodid25519": "1.0.2", - "jsbn": "0.1.1", - "tweetnacl": "0.14.5" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "string_decoder": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "requires": { - "safe-buffer": "5.0.1" - } - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" - } - }, - "stringstream": { - "version": "0.0.5", - "bundled": true, - "dev": true, - "optional": true - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "2.2.1", - "bundled": true, - "dev": true, - "requires": { - "block-stream": "0.0.9", - "fstream": "1.0.11", - "inherits": "2.0.3" - } - }, - "tar-pack": { - "version": "3.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "2.6.8", - "fstream": "1.0.11", - "fstream-ignore": "1.0.5", - "once": "1.4.0", - "readable-stream": "2.2.9", - "rimraf": "2.6.1", - "tar": "2.2.1", - "uid-number": "0.0.6" - } - }, - "tough-cookie": { - "version": "2.3.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "punycode": "1.4.1" - } - }, - "tunnel-agent": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "5.0.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "bundled": true, - "dev": true, - "optional": true - }, - "uid-number": { - "version": "0.0.6", - "bundled": true, - "dev": true, - "optional": true - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true - }, - "uuid": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "verror": { - "version": "1.3.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "extsprintf": "1.0.2" - } - }, - "wide-align": { - "version": "1.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "1.0.2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true - } - } - }, - "function-bind": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.0.tgz", - "integrity": "sha1-FhdnFMgBeY5Ojyz391KUZ7tKV3E=", - "dev": true - }, - "function-name-support": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/function-name-support/-/function-name-support-0.2.0.tgz", - "integrity": "sha1-VdO/qm6v1QWlD5vIH99XVkoLsHE=", - "dev": true - }, - "generate-function": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz", - "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ=", - "dev": true - }, - "generate-object-property": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz", - "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=", - "dev": true, - "requires": { - "is-property": "1.0.2" - } - }, - "get-caller-file": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", - "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", - "dev": true - }, - "get-port": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.1.0.tgz", - "integrity": "sha1-7wGxioTKZIaXD/meVERhQac//T4=", - "dev": true - }, - "get-proxy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/get-proxy/-/get-proxy-2.1.0.tgz", - "integrity": "sha512-zmZIaQTWnNQb4R4fJUEp/FC51eZsc6EkErspy3xtIYStaq8EB/hDIWipxsal+E8rz0qD7f2sL/NA9Xee4RInJw==", - "dev": true, - "requires": { - "npm-conf": "1.1.2" - } - }, - "get-set-props": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-set-props/-/get-set-props-0.1.0.tgz", - "integrity": "sha1-mYR1wXhEVobQsyJG2l3428++jqM=", - "dev": true - }, - "get-stdin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", - "dev": true - }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - }, - "getpass": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", - "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", - "dev": true, - "requires": { - "assert-plus": "1.0.0" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } - } - }, - "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", - "dev": true, - "requires": { - "fs.realpath": "1.0.0", - "inflight": "1.0.6", - "inherits": "2.0.3", - "minimatch": "3.0.4", - "once": "1.4.0", - "path-is-absolute": "1.0.1" - } - }, - "glob-base": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-base/-/glob-base-0.3.0.tgz", - "integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=", - "dev": true, - "requires": { - "glob-parent": "2.0.0", - "is-glob": "2.0.1" - } - }, - "glob-parent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", - "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "dev": true, - "requires": { - "is-glob": "2.0.1" - } - }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==", - "dev": true - }, - "globby": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", - "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", - "dev": true, - "requires": { - "array-union": "1.0.2", - "glob": "7.1.2", - "object-assign": "4.1.1", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" - }, - "dependencies": { - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "2.0.4" - } - } - } - }, - "got": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", - "integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=", - "dev": true, - "requires": { - "create-error-class": "3.0.2", - "duplexer3": "0.1.4", - "get-stream": "3.0.0", - "is-redirect": "1.0.0", - "is-retry-allowed": "1.1.0", - "is-stream": "1.1.0", - "lowercase-keys": "1.0.0", - "safe-buffer": "5.1.1", - "timed-out": "4.0.1", - "unzip-response": "2.0.1", - "url-parse-lax": "1.0.0" - } - }, - "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true - }, - "graceful-readlink": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", - "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", - "dev": true - }, - "har-schema": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz", - "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=", - "dev": true - }, - "har-validator": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz", - "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=", - "dev": true, - "requires": { - "ajv": "4.11.8", - "har-schema": "1.0.5" - } - }, - "has": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", - "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", - "dev": true, - "requires": { - "function-bind": "1.1.0" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - } - } - }, - "has-binary": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/has-binary/-/has-binary-0.1.7.tgz", - "integrity": "sha1-aOYesWIQyVRaClzOBqhzkS/h5ow=", - "dev": true, - "requires": { - "isarray": "0.0.1" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - } - } - }, - "has-color": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz", - "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=", - "dev": true - }, - "has-cors": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz", - "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=", - "dev": true - }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", - "dev": true - }, - "has-symbol-support-x": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.0.tgz", - "integrity": "sha512-F1NtLDtW9NyUrS3faUcI1yVFHCTXyzPb1jfrZBQi5NHxFPlXxZnFLFGzfA2DsdmgCxv2MZ0+bfcgC4EZTmk4SQ==", - "dev": true - }, - "has-to-string-tag-x": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.0.tgz", - "integrity": "sha512-R3OdOP9j6AH5hS1yXeu9wAS+iKSZQx/CC6aMdN6WiaqPlBoA2S+47MtoMsZgKr2m0eAJ+73WWGX0RaFFE5XWKA==", - "dev": true, - "requires": { - "has-symbol-support-x": "1.4.0" - } - }, - "has-yarn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-yarn/-/has-yarn-1.0.0.tgz", - "integrity": "sha1-ieJdtgS3Jcj1l2//Ct3JIbgopac=", - "dev": true - }, - "hash-base": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz", - "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=", - "dev": true, - "requires": { - "inherits": "2.0.3" - } - }, - "hash.js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", - "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", - "dev": true, - "requires": { - "inherits": "2.0.3", - "minimalistic-assert": "1.0.0" - } - }, - "hawk": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz", - "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=", - "dev": true, - "requires": { - "boom": "2.10.1", - "cryptiles": "2.0.5", - "hoek": "2.16.3", - "sntp": "1.0.9" - } - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "1.1.3", - "minimalistic-assert": "1.0.0", - "minimalistic-crypto-utils": "1.0.1" - } - }, - "hoek": { - "version": "2.16.3", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz", - "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=", - "dev": true - }, - "home-or-tmp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", - "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", - "dev": true, - "requires": { - "os-homedir": "1.0.2", - "os-tmpdir": "1.0.2" - } - }, - "hosted-git-info": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz", - "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg==", - "dev": true - }, - "http-signature": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz", - "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=", - "dev": true, - "requires": { - "assert-plus": "0.2.0", - "jsprim": "1.4.0", - "sshpk": "1.13.1" - } - }, - "https-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-0.0.1.tgz", - "integrity": "sha1-P5E2XKvmC3ftDruiS0VOPgnZWoI=", - "dev": true - }, - "hullabaloo-config-manager": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/hullabaloo-config-manager/-/hullabaloo-config-manager-1.1.1.tgz", - "integrity": "sha512-ztKnkZV0TmxnumCDHHgLGNiDnotu4EHCp9YMkznWuo4uTtCyJ+cu+RNcxUeXYKTllpvLFWnbfWry09yzszgg+A==", - "dev": true, - "requires": { - "dot-prop": "4.2.0", - "es6-error": "4.0.2", - "graceful-fs": "4.1.11", - "indent-string": "3.2.0", - "json5": "0.5.1", - "lodash.clonedeep": "4.5.0", - "lodash.clonedeepwith": "4.5.0", - "lodash.isequal": "4.5.0", - "lodash.merge": "4.6.0", - "md5-hex": "2.0.0", - "package-hash": "2.0.0", - "pkg-dir": "2.0.0", - "resolve-from": "3.0.0", - "safe-buffer": "5.1.1" - } - }, - "iconv-lite": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.18.tgz", - "integrity": "sha512-sr1ZQph3UwHTR0XftSbK85OvBbxe/abLGzEnPENCQwmHf7sck8Oyu4ob3LgBxWWxRoM+QszeUyl7jbqapu2TqA==", - "dev": true - }, - "ieee754": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz", - "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=", - "dev": true - }, - "ignore": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.3.tgz", - "integrity": "sha1-QyNS5XrM2HqzEQ6C0/6g5HgSFW0=", - "dev": true - }, - "ignore-by-default": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ignore-by-default/-/ignore-by-default-1.0.1.tgz", - "integrity": "sha1-SMptcvbGo68Aqa1K5odr44ieKwk=", - "dev": true - }, - "import-lazy": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-2.1.0.tgz", - "integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=", - "dev": true - }, - "import-local": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-0.1.1.tgz", - "integrity": "sha1-sReVcqrNwRxqkQCftDDbyrX2aKg=", - "dev": true, - "requires": { - "pkg-dir": "2.0.0", - "resolve-cwd": "2.0.0" - } - }, - "import-modules": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/import-modules/-/import-modules-1.1.0.tgz", - "integrity": "sha1-dI23nFzEK7lwHvq0JPiU5yYA6dw=", - "dev": true - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "in-publish": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz", - "integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E=", - "dev": true - }, - "indent-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", - "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", - "dev": true - }, - "indexof": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz", - "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10=", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "1.4.0", - "wrappy": "1.0.2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "ini": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz", - "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=", - "dev": true - }, - "inquirer": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.2.1.tgz", - "integrity": "sha512-QgW3eiPN8gpj/K5vVpHADJJgrrF0ho/dZGylikGX7iqAdRgC9FVKYKWFLx6hZDBFcOLEoSqINYrVPeFAeG/PdA==", - "dev": true, - "requires": { - "ansi-escapes": "2.0.0", - "chalk": "2.0.1", - "cli-cursor": "2.1.0", - "cli-width": "2.1.0", - "external-editor": "2.0.4", - "figures": "2.0.0", - "lodash": "4.17.4", - "mute-stream": "0.0.7", - "run-async": "2.3.0", - "rx-lite": "4.0.8", - "rx-lite-aggregates": "4.0.8", - "string-width": "2.1.1", - "strip-ansi": "4.0.0", - "through": "2.3.8" - } - }, - "interpret": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.3.tgz", - "integrity": "sha1-y8NcYu7uc/Gat7EKgBURQBr8D5A=", - "dev": true - }, - "invariant": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz", - "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=", - "dev": true, - "requires": { - "loose-envify": "1.3.1" - } - }, - "invert-kv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true - }, - "irregular-plurals": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-1.3.0.tgz", - "integrity": "sha512-njf5A+Mxb3kojuHd1DzISjjIl+XhyzovXEOyPPSzdQozq/Lf2tN27mOrAAsxEPZxpn6I4MGzs1oo9TxXxPFpaA==", - "dev": true - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "1.9.0" - } - }, - "is-buffer": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", - "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=", - "dev": true - }, - "is-builtin-module": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", - "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", - "dev": true, - "requires": { - "builtin-modules": "1.1.1" - } - }, - "is-ci": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.0.10.tgz", - "integrity": "sha1-9zkzayYyNlBhqdSCcM1WrjNpMY4=", - "dev": true, - "requires": { - "ci-info": "1.0.0" - } - }, - "is-dotfile": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz", - "integrity": "sha1-pqLzL/0t+wT1yiXs0Pa4PPeYoeE=", - "dev": true - }, - "is-equal-shallow": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", - "integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=", - "dev": true, - "requires": { - "is-primitive": "2.0.0" - } - }, - "is-error": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-error/-/is-error-2.2.1.tgz", - "integrity": "sha1-aEqW2EB2V3yY9M20DG0mpRI78Zw=", - "dev": true - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "dev": true - }, - "is-finite": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", - "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", - "dev": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-generator-fn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-1.0.0.tgz", - "integrity": "sha1-lp1J4bszKfa7fwkIm+JleLLd1Go=", - "dev": true - }, - "is-get-set-prop": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-get-set-prop/-/is-get-set-prop-1.0.0.tgz", - "integrity": "sha1-JzGHfk14pqae3M5rudaLB3nnYxI=", - "dev": true, - "requires": { - "get-set-props": "0.1.0", - "lowercase-keys": "1.0.0" - } - }, - "is-glob": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", - "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "dev": true, - "requires": { - "is-extglob": "1.0.0" - } - }, - "is-js-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-js-type/-/is-js-type-2.0.0.tgz", - "integrity": "sha1-c2FwBtZZtOtHKbunR9KHgt8PfiI=", - "dev": true, - "requires": { - "js-types": "1.0.0" - } - }, - "is-my-json-valid": { - "version": "2.16.0", - "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.0.tgz", - "integrity": "sha1-8Hndm/2uZe4gOKrorLyGqxCeNpM=", - "dev": true, - "requires": { - "generate-function": "2.0.0", - "generate-object-property": "1.2.0", - "jsonpointer": "4.0.1", - "xtend": "4.0.1" - } - }, - "is-natural-number": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", - "integrity": "sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=", - "dev": true - }, - "is-npm": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-npm/-/is-npm-1.0.0.tgz", - "integrity": "sha1-8vtjpl5JBbQGyGBydloaTceTufQ=", - "dev": true - }, - "is-number": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz", - "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - } - }, - "is-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", - "dev": true - }, - "is-obj-prop": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-obj-prop/-/is-obj-prop-1.0.0.tgz", - "integrity": "sha1-s03nnEULjXxzqyzfZ9yHWtuF+A4=", - "dev": true, - "requires": { - "lowercase-keys": "1.0.0", - "obj-props": "1.1.0" - } - }, - "is-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-object/-/is-object-1.0.1.tgz", - "integrity": "sha1-iVJojF7C/9awPsyF52ngKQMINHA=", - "dev": true - }, - "is-observable": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/is-observable/-/is-observable-0.2.0.tgz", - "integrity": "sha1-s2ExHYPG5dcmyr9eJQsCNxBvWuI=", - "dev": true, - "requires": { - "symbol-observable": "0.2.4" - } - }, - "is-path-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", - "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", - "dev": true - }, - "is-path-in-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", - "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", - "dev": true, - "requires": { - "is-path-inside": "1.0.0" - } - }, - "is-path-inside": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz", - "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=", - "dev": true, - "requires": { - "path-is-inside": "1.0.2" - } - }, - "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", - "dev": true - }, - "is-posix-bracket": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz", - "integrity": "sha1-MzTceXdDaOkvAW5vvAqI9c1ua8Q=", - "dev": true - }, - "is-primitive": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-primitive/-/is-primitive-2.0.0.tgz", - "integrity": "sha1-IHurkWOEmcB7Kt8kCkGochADRXU=", - "dev": true - }, - "is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", - "dev": true - }, - "is-property": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", - "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ=", - "dev": true - }, - "is-proto-prop": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-proto-prop/-/is-proto-prop-1.0.0.tgz", - "integrity": "sha1-s5UflcCJkk+11PzaZUKrPoPisiA=", - "dev": true, - "requires": { - "lowercase-keys": "1.0.0", - "proto-props": "0.2.1" - } - }, - "is-redirect": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-redirect/-/is-redirect-1.0.0.tgz", - "integrity": "sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=", - "dev": true - }, - "is-resolvable": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz", - "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=", - "dev": true, - "requires": { - "tryit": "1.0.3" - } - }, - "is-retry-allowed": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", - "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=", - "dev": true - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "is-url": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.2.tgz", - "integrity": "sha1-SYkFpZO/R8wtnn9zg3K792lsfyY=", - "dev": true - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - }, - "isstream": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", - "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", - "dev": true - }, - "isurl": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isurl/-/isurl-1.0.0.tgz", - "integrity": "sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w==", - "dev": true, - "requires": { - "has-to-string-tag-x": "1.4.0", - "is-object": "1.0.1" - } - }, - "js-string-escape": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", - "integrity": "sha1-4mJbrbwNZ8dTPp7cEGjFh65BN+8=", - "dev": true - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", - "dev": true - }, - "js-types": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/js-types/-/js-types-1.0.0.tgz", - "integrity": "sha1-0kLmSU7Vcq08koCfyL7X92h8vwM=", - "dev": true - }, - "js-yaml": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.9.0.tgz", - "integrity": "sha512-0LoUNELX4S+iofCT8f4uEHIiRBR+c2AINyC8qRWfC6QNruLtxVZRJaPcu/xwMgFIgDxF25tGHaDjvxzJCNE9yw==", - "dev": true, - "requires": { - "argparse": "1.0.9", - "esprima": "4.0.0" - } - }, - "jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", - "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true, - "optional": true - }, - "jschardet": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/jschardet/-/jschardet-1.5.0.tgz", - "integrity": "sha512-+Q8JsoEQbrdE+a/gg1F9XO92gcKXgpE5UACqr0sIubjDmBEkd+OOWPGzQeMrWSLxd73r4dHxBeRW7edHu5LmJQ==", - "dev": true - }, - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", - "dev": true - }, - "json-loader": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/json-loader/-/json-loader-0.5.7.tgz", - "integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==", - "dev": true - }, - "json-schema": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz", - "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=", - "dev": true - }, - "json-schema-traverse": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz", - "integrity": "sha1-NJptRMU6Ud6JtAgFxdXlm0F9M0A=", - "dev": true - }, - "json-stable-stringify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz", - "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=", - "dev": true, - "requires": { - "jsonify": "0.0.0" - } - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true - }, - "json3": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.2.tgz", - "integrity": "sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=", - "dev": true - }, - "json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", - "dev": true - }, - "jsonfile": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", - "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11" - } - }, - "jsonify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", - "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", - "dev": true - }, - "jsonpointer": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz", - "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=", - "dev": true - }, - "jsprim": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.0.tgz", - "integrity": "sha1-o7h+QCmNjDgFUtjMdiigu5WiKRg=", - "dev": true, - "requires": { - "assert-plus": "1.0.0", - "extsprintf": "1.0.2", - "json-schema": "0.2.3", - "verror": "1.3.6" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.5" - } - }, - "last-line-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/last-line-stream/-/last-line-stream-1.0.0.tgz", - "integrity": "sha1-0bZNafhv8kry0EiDos7uFFIKVgA=", - "dev": true, - "requires": { - "through2": "2.0.3" - } - }, - "latest-version": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz", - "integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=", - "dev": true, - "requires": { - "package-json": "4.0.1" - } - }, - "lazy-cache": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz", - "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=", - "dev": true - }, - "lcid": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", - "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, - "requires": { - "invert-kv": "1.0.0" - } - }, - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "1.1.2", - "type-check": "0.3.2" - } - }, - "lint-staged": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-4.0.2.tgz", - "integrity": "sha1-joPhHp4WVsCbYRf22w1V/UlgocA=", - "dev": true, - "requires": { - "app-root-path": "2.0.1", - "cosmiconfig": "1.1.0", - "execa": "0.7.0", - "listr": "0.12.0", - "lodash.chunk": "4.2.0", - "minimatch": "3.0.4", - "npm-which": "3.0.1", - "p-map": "1.1.1", - "staged-git-files": "0.0.4" - } - }, - "listr": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/listr/-/listr-0.12.0.tgz", - "integrity": "sha1-a84sD1YD+klYDqF81qAMwOX6RRo=", - "dev": true, - "requires": { - "chalk": "1.1.3", - "cli-truncate": "0.2.1", - "figures": "1.7.0", - "indent-string": "2.1.0", - "is-promise": "2.1.0", - "is-stream": "1.1.0", - "listr-silent-renderer": "1.1.1", - "listr-update-renderer": "0.2.0", - "listr-verbose-renderer": "0.4.0", - "log-symbols": "1.0.2", - "log-update": "1.0.2", - "ora": "0.2.3", - "p-map": "1.1.1", - "rxjs": "5.4.2", - "stream-to-observable": "0.1.0", - "strip-ansi": "3.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, - "cli-cursor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", - "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", - "dev": true, - "requires": { - "restore-cursor": "1.0.1" - } - }, - "cli-spinners": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-0.1.2.tgz", - "integrity": "sha1-u3ZNiOGF+54eaiofGXcjGPYF4xw=", - "dev": true - }, - "cli-truncate": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz", - "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=", - "dev": true, - "requires": { - "slice-ansi": "0.0.4", - "string-width": "1.0.2" - } - }, - "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", - "dev": true, - "requires": { - "escape-string-regexp": "1.0.5", - "object-assign": "4.1.1" - } - }, - "indent-string": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", - "dev": true, - "requires": { - "repeating": "2.0.1" - } - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, - "onetime": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", - "dev": true - }, - "ora": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/ora/-/ora-0.2.3.tgz", - "integrity": "sha1-N1J9Igrc1Tw5tzVx11QVbV22V6Q=", - "dev": true, - "requires": { - "chalk": "1.1.3", - "cli-cursor": "1.0.2", - "cli-spinners": "0.1.2", - "object-assign": "4.1.1" - } - }, - "restore-cursor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", - "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", - "dev": true, - "requires": { - "exit-hook": "1.1.1", - "onetime": "1.1.0" - } - }, - "slice-ansi": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", - "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", - "dev": true - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "listr-silent-renderer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz", - "integrity": "sha1-kktaN1cVN3C/Go4/v3S4u/P5JC4=", - "dev": true - }, - "listr-update-renderer": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.2.0.tgz", - "integrity": "sha1-yoDhd5tOcCZoB+ju0a1qvjmFUPk=", - "dev": true, - "requires": { - "chalk": "1.1.3", - "cli-truncate": "0.2.1", - "elegant-spinner": "1.0.1", - "figures": "1.7.0", - "indent-string": "3.2.0", - "log-symbols": "1.0.2", - "log-update": "1.0.2", - "strip-ansi": "3.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, - "cli-truncate": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-0.2.1.tgz", - "integrity": "sha1-nxXPuwcFAFNpIWxiasfQWrkN1XQ=", - "dev": true, - "requires": { - "slice-ansi": "0.0.4", - "string-width": "1.0.2" - } - }, - "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", - "dev": true, - "requires": { - "escape-string-regexp": "1.0.5", - "object-assign": "4.1.1" - } - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, - "slice-ansi": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", - "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", - "dev": true - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "listr-verbose-renderer": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.4.0.tgz", - "integrity": "sha1-RNwBuww0oDxXIVTU0Izemx3FYg8=", - "dev": true, - "requires": { - "chalk": "1.1.3", - "cli-cursor": "1.0.2", - "date-fns": "1.28.5", - "figures": "1.7.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, - "cli-cursor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", - "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", - "dev": true, - "requires": { - "restore-cursor": "1.0.1" - } - }, - "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", - "dev": true, - "requires": { - "escape-string-regexp": "1.0.5", - "object-assign": "4.1.1" - } - }, - "onetime": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", - "dev": true - }, - "restore-cursor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", - "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", - "dev": true, - "requires": { - "exit-hook": "1.1.1", - "onetime": "1.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "load-json-file": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "strip-bom": "3.0.0" - } - }, - "loader-runner": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.3.0.tgz", - "integrity": "sha1-9IKuqC1UPgeSFwDVpG7yb9rGuKI=", - "dev": true - }, - "loader-utils": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", - "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", - "dev": true, - "requires": { - "big.js": "3.1.3", - "emojis-list": "2.1.0", - "json5": "0.5.1" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "2.0.0", - "path-exists": "3.0.0" - } - }, - "lodash": { - "version": "4.17.4", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz", - "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4=", - "dev": true - }, - "lodash.camelcase": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", - "dev": true - }, - "lodash.chunk": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.chunk/-/lodash.chunk-4.2.0.tgz", - "integrity": "sha1-ZuXOH3btJ7QwPYxlEujRIW6BBrw=", - "dev": true - }, - "lodash.clonedeep": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", - "dev": true - }, - "lodash.clonedeepwith": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.clonedeepwith/-/lodash.clonedeepwith-4.5.0.tgz", - "integrity": "sha1-buMFc6A6GmDWcKYu8zwQzxr9vdQ=", - "dev": true - }, - "lodash.cond": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz", - "integrity": "sha1-9HGh2khr5g9quVXRcRVSPdHSVdU=", - "dev": true - }, - "lodash.debounce": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz", - "integrity": "sha1-gteb/zCmfEAF/9XiUVMArZyk168=", - "dev": true - }, - "lodash.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha1-8xwiIlqWMtK7+OSt2+8kCqdlph8=", - "dev": true - }, - "lodash.flattendeep": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha1-+wMJF/hqMTTlvJvsDWngAT3f7bI=", - "dev": true - }, - "lodash.isequal": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=", - "dev": true - }, - "lodash.isplainobject": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", - "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=", - "dev": true - }, - "lodash.kebabcase": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz", - "integrity": "sha1-hImxyw0p/4gZXM7KRI/21swpXDY=", - "dev": true - }, - "lodash.merge": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.0.tgz", - "integrity": "sha1-aYhLoUSsM/5plzemCG3v+t0PicU=", - "dev": true - }, - "lodash.range": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/lodash.range/-/lodash.range-3.2.0.tgz", - "integrity": "sha1-9GHliPZmg/fq3q3lE+OKaaVloV0=", - "dev": true - }, - "lodash.snakecase": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz", - "integrity": "sha1-OdcUo1NXFHg3rv1ktdy7Fr7Nj40=", - "dev": true - }, - "lodash.upperfirst": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz", - "integrity": "sha1-E2Xt9DFIBIHvDRxolXpe2Z1J984=", - "dev": true - }, - "log-symbols": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-1.0.2.tgz", - "integrity": "sha1-N2/3tY6jCGoPCfrMdGF+ylAeGhg=", - "dev": true, - "requires": { - "chalk": "1.1.3" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "log-update": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-1.0.2.tgz", - "integrity": "sha1-GZKfZMQJPS0ucHWh2tivWcKWuNE=", - "dev": true, - "requires": { - "ansi-escapes": "1.4.0", - "cli-cursor": "1.0.2" - }, - "dependencies": { - "ansi-escapes": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", - "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", - "dev": true - }, - "cli-cursor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz", - "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=", - "dev": true, - "requires": { - "restore-cursor": "1.0.1" - } - }, - "onetime": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", - "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", - "dev": true - }, - "restore-cursor": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz", - "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=", - "dev": true, - "requires": { - "exit-hook": "1.1.1", - "onetime": "1.1.0" - } - } - } - }, - "longest": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", - "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=", - "dev": true - }, - "loose-envify": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", - "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", - "dev": true, - "requires": { - "js-tokens": "3.0.2" - } - }, - "loud-rejection": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", - "dev": true, - "requires": { - "currently-unhandled": "0.4.1", - "signal-exit": "3.0.2" - } - }, - "lowercase-keys": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz", - "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=", - "dev": true - }, - "lru-cache": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", - "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", - "dev": true, - "requires": { - "pseudomap": "1.0.2", - "yallist": "2.1.2" - } - }, - "make-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.0.0.tgz", - "integrity": "sha1-l6ARdR6R3YfPre9Ygy67BJNt6Xg=", - "dev": true, - "requires": { - "pify": "2.3.0" - } - }, - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", - "dev": true - }, - "matcher": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-1.0.0.tgz", - "integrity": "sha1-qvDEgW62m5IJRnQXViXzRmsOPhk=", - "dev": true, - "requires": { - "escape-string-regexp": "1.0.5" - } - }, - "md5-hex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/md5-hex/-/md5-hex-2.0.0.tgz", - "integrity": "sha1-0FiOnxx0lUSS7NJKwKxs6ZfZLjM=", - "dev": true, - "requires": { - "md5-o-matic": "0.1.1" - } - }, - "md5-o-matic": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/md5-o-matic/-/md5-o-matic-0.1.1.tgz", - "integrity": "sha1-givM1l4RfFFPqxdrJZRdVBAKA8M=", - "dev": true - }, - "mem": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz", - "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=", - "dev": true, - "requires": { - "mimic-fn": "1.1.0" - } - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "0.1.4", - "readable-stream": "2.3.3" - } - }, - "meow": { - "version": "3.7.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", - "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", - "dev": true, - "requires": { - "camelcase-keys": "2.1.0", - "decamelize": "1.2.0", - "loud-rejection": "1.6.0", - "map-obj": "1.0.1", - "minimist": "1.2.0", - "normalize-package-data": "2.4.0", - "object-assign": "4.1.1", - "read-pkg-up": "1.0.1", - "redent": "1.0.0", - "trim-newlines": "1.0.0" - }, - "dependencies": { - "find-up": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", - "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", - "dev": true, - "requires": { - "path-exists": "2.1.0", - "pinkie-promise": "2.0.1" - } - }, - "load-json-file": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", - "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "parse-json": "2.2.0", - "pify": "2.3.0", - "pinkie-promise": "2.0.1", - "strip-bom": "2.0.0" - } - }, - "path-exists": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", - "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", - "dev": true, - "requires": { - "pinkie-promise": "2.0.1" - } - }, - "path-type": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", - "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "pify": "2.3.0", - "pinkie-promise": "2.0.1" - } - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "2.0.4" - } - }, - "read-pkg": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", - "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", - "dev": true, - "requires": { - "load-json-file": "1.1.0", - "normalize-package-data": "2.4.0", - "path-type": "1.1.0" - } - }, - "read-pkg-up": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz", - "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=", - "dev": true, - "requires": { - "find-up": "1.1.2", - "read-pkg": "1.1.0" - } - }, - "strip-bom": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", - "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", - "dev": true, - "requires": { - "is-utf8": "0.2.1" - } - } - } - }, - "micromatch": { - "version": "2.3.11", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz", - "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=", - "dev": true, - "requires": { - "arr-diff": "2.0.0", - "array-unique": "0.2.1", - "braces": "1.8.5", - "expand-brackets": "0.1.5", - "extglob": "0.3.2", - "filename-regex": "2.0.1", - "is-extglob": "1.0.0", - "is-glob": "2.0.1", - "kind-of": "3.2.2", - "normalize-path": "2.1.1", - "object.omit": "2.0.1", - "parse-glob": "3.0.4", - "regex-cache": "0.4.3" - }, - "dependencies": { - "array-unique": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz", - "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=", - "dev": true - } - } - }, - "miller-rabin": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.0.tgz", - "integrity": "sha1-SmL7HUKTPAVYOYL0xxb2+55sbT0=", - "dev": true, - "requires": { - "bn.js": "4.11.7", - "brorand": "1.1.0" - } - }, - "mime-db": { - "version": "1.29.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.29.0.tgz", - "integrity": "sha1-SNJtI1WJZRcErFkWygYAGRQmaHg=", - "dev": true - }, - "mime-types": { - "version": "2.1.16", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.16.tgz", - "integrity": "sha1-K4WKUuXs1RbbiXrCvodIeDBpjiM=", - "dev": true, - "requires": { - "mime-db": "1.29.0" - } - }, - "mimic-fn": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", - "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=", - "dev": true - }, - "mimic-response": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.0.tgz", - "integrity": "sha1-3z02Uqc/3ta5sLJBRub9BSNTRY4=", - "dev": true - }, - "minimalistic-assert": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz", - "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M=", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, - "requires": { - "brace-expansion": "1.1.8" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "dev": true, - "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - } - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "multimatch": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", - "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=", - "dev": true, - "requires": { - "array-differ": "1.0.0", - "array-union": "1.0.2", - "arrify": "1.0.1", - "minimatch": "3.0.4" - } - }, - "multistream": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/multistream/-/multistream-2.1.0.tgz", - "integrity": "sha1-YlwmfVxEQkrWKUeItbtNo9yzLx0=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "readable-stream": "2.3.3" - } - }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", - "dev": true - }, - "nan": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.6.2.tgz", - "integrity": "sha1-5P805slf37WuzAjeZZb0NgWn20U=", - "dev": true, - "optional": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "node-fetch": { - "version": "1.7.1", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.1.tgz", - "integrity": "sha512-j8XsFGCLw79vWXkZtMSmmLaOk9z5SQ9bV/tkbZVCqvgwzrjAGq66igobLofHtF63NvMTp2WjytpsNTGKa+XRIQ==", - "dev": true, - "requires": { - "encoding": "0.1.12", - "is-stream": "1.1.0" - } - }, - "node-libs-browser": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.0.0.tgz", - "integrity": "sha1-o6WeyXAkmFtG6Vg3lkb5bEthZkY=", - "dev": true, - "requires": { - "assert": "1.4.1", - "browserify-zlib": "0.1.4", - "buffer": "4.9.1", - "console-browserify": "1.1.0", - "constants-browserify": "1.0.0", - "crypto-browserify": "3.11.1", - "domain-browser": "1.1.7", - "events": "1.1.1", - "https-browserify": "0.0.1", - "os-browserify": "0.2.1", - "path-browserify": "0.0.0", - "process": "0.11.10", - "punycode": "1.4.1", - "querystring-es3": "0.2.1", - "readable-stream": "2.3.3", - "stream-browserify": "2.0.1", - "stream-http": "2.7.2", - "string_decoder": "0.10.31", - "timers-browserify": "2.0.2", - "tty-browserify": "0.0.0", - "url": "0.11.0", - "util": "0.10.3", - "vm-browserify": "0.0.4" - }, - "dependencies": { - "base64-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz", - "integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw==", - "dev": true - }, - "buffer": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", - "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", - "dev": true, - "requires": { - "base64-js": "1.2.1", - "ieee754": "1.1.8", - "isarray": "1.0.0" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - } - } - }, - "normalize-package-data": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", - "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", - "dev": true, - "requires": { - "hosted-git-info": "2.5.0", - "is-builtin-module": "1.0.0", - "semver": "5.4.1", - "validate-npm-package-license": "3.0.1" - } - }, - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "1.0.2" - } - }, - "npm-conf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.2.tgz", - "integrity": "sha512-dotwbpwVzfNB/2EF3A2wjK5tEMLggKfuA/8TG6WvBB1Zrv+JsvF7E8ei9B/HGq211st/GwXFbREcNJvJ1eySUQ==", - "dev": true, - "requires": { - "config-chain": "1.1.11", - "pify": "3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - } - } - }, - "npm-path": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/npm-path/-/npm-path-2.0.3.tgz", - "integrity": "sha1-Fc/04ciaONp39W9gVbJPl137K74=", - "dev": true, - "requires": { - "which": "1.3.0" - } - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "requires": { - "path-key": "2.0.1" - } - }, - "npm-which": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/npm-which/-/npm-which-3.0.1.tgz", - "integrity": "sha1-kiXybsOihcIJyuZ8OxGmtKtxQKo=", - "dev": true, - "requires": { - "commander": "2.11.0", - "npm-path": "2.0.3", - "which": "1.3.0" - }, - "dependencies": { - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", - "dev": true - } - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", - "dev": true - }, - "oauth-sign": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", - "dev": true - }, - "obj-props": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/obj-props/-/obj-props-1.1.0.tgz", - "integrity": "sha1-YmMT+qRCvv1KROmgLDy2vek3tRE=", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-component": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz", - "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE=", - "dev": true - }, - "object.omit": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-2.0.1.tgz", - "integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=", - "dev": true, - "requires": { - "for-own": "0.1.5", - "is-extendable": "0.1.1" - } - }, - "observable-to-promise": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/observable-to-promise/-/observable-to-promise-0.5.0.tgz", - "integrity": "sha1-yCjw8NxH6fhq+KSXfF1VB2znqR8=", - "dev": true, - "requires": { - "is-observable": "0.2.0", - "symbol-observable": "1.0.4" - }, - "dependencies": { - "symbol-observable": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.4.tgz", - "integrity": "sha1-Kb9hXUqnEhvdiYsi1LP5vE4qoD0=", - "dev": true - } - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1.0.2" - } - }, - "onetime": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", - "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", - "dev": true, - "requires": { - "mimic-fn": "1.1.0" - } - }, - "option-chain": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/option-chain/-/option-chain-1.0.0.tgz", - "integrity": "sha1-k41zvU4Xg/lI00AjZEraI2aeMPI=", - "dev": true - }, - "optionator": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", - "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", - "dev": true, - "requires": { - "deep-is": "0.1.3", - "fast-levenshtein": "2.0.6", - "levn": "0.3.0", - "prelude-ls": "1.1.2", - "type-check": "0.3.2", - "wordwrap": "1.0.0" - } - }, - "options": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/options/-/options-0.0.6.tgz", - "integrity": "sha1-7CLTEoBrtT5zF3Pnza788cZDEo8=", - "dev": true - }, - "ora": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/ora/-/ora-1.3.0.tgz", - "integrity": "sha1-gAeN0rkqk0r2ajrXKluRBpTt5Ro=", - "dev": true, - "requires": { - "chalk": "1.1.3", - "cli-cursor": "2.1.0", - "cli-spinners": "1.0.0", - "log-symbols": "1.0.2" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "os-browserify": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.2.1.tgz", - "integrity": "sha1-Y/xMzuXS13Y9Jrv4YBB45sLgBE8=", - "dev": true - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", - "dev": true - }, - "os-locale": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", - "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", - "dev": true, - "requires": { - "execa": "0.7.0", - "lcid": "1.0.0", - "mem": "1.1.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true - }, - "p-cancelable": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-0.3.0.tgz", - "integrity": "sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw==", - "dev": true - }, - "p-event": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-event/-/p-event-1.3.0.tgz", - "integrity": "sha1-jmtPT2XHK8W2/ii3XtqHT5akoIU=", - "dev": true, - "requires": { - "p-timeout": "1.2.0" - } - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, - "p-limit": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz", - "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw=", - "dev": true - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "1.1.0" - } - }, - "p-map": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.1.1.tgz", - "integrity": "sha1-BfXkrpegaDcbwqXMhr+9vBnErno=", - "dev": true - }, - "p-timeout": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-1.2.0.tgz", - "integrity": "sha1-mCD5lDTFgXhotPNICe5SkWYNW2w=", - "dev": true, - "requires": { - "p-finally": "1.0.0" - } - }, - "package-hash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-2.0.0.tgz", - "integrity": "sha1-eK4ybIngWk2BO2hgGXevBcANKg0=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "lodash.flattendeep": "4.4.0", - "md5-hex": "2.0.0", - "release-zalgo": "1.0.0" - } - }, - "package-json": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz", - "integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=", - "dev": true, - "requires": { - "got": "6.7.1", - "registry-auth-token": "3.3.1", - "registry-url": "3.1.0", - "semver": "5.4.1" - } - }, - "pako": { - "version": "0.2.9", - "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", - "integrity": "sha1-8/dSL073gjSNqBYbrZ7P1Rv4OnU=", - "dev": true - }, - "parse-asn1": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz", - "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=", - "dev": true, - "requires": { - "asn1.js": "4.9.1", - "browserify-aes": "1.0.6", - "create-hash": "1.1.3", - "evp_bytestokey": "1.0.0", - "pbkdf2": "3.0.12" - } - }, - "parse-glob": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/parse-glob/-/parse-glob-3.0.4.tgz", - "integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=", - "dev": true, - "requires": { - "glob-base": "0.3.0", - "is-dotfile": "1.0.3", - "is-extglob": "1.0.0", - "is-glob": "2.0.1" - } - }, - "parse-json": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", - "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", - "dev": true, - "requires": { - "error-ex": "1.3.1" - } - }, - "parse-ms": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-1.0.1.tgz", - "integrity": "sha1-VjRtR0nXjyNDDKDHE4UK75GqNh0=", - "dev": true - }, - "parsejson": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/parsejson/-/parsejson-0.0.3.tgz", - "integrity": "sha1-q343WfIJ7OmUN5c/fQ8fZK4OZKs=", - "dev": true, - "requires": { - "better-assert": "1.0.2" - } - }, - "parseqs": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz", - "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=", - "dev": true, - "requires": { - "better-assert": "1.0.2" - } - }, - "parseuri": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz", - "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=", - "dev": true, - "requires": { - "better-assert": "1.0.2" - } - }, - "path-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.0.tgz", - "integrity": "sha1-oLhwcpquIUAFt9UDLsLLuw+0RRo=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "path-parse": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", - "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", - "dev": true - }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true, - "requires": { - "pify": "2.3.0" - } - }, - "pbkdf2": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.12.tgz", - "integrity": "sha1-vjZ4XFBn6kjYBv+SMojF91C2uKI=", - "dev": true, - "requires": { - "create-hash": "1.1.3", - "create-hmac": "1.1.6", - "ripemd160": "2.0.1", - "safe-buffer": "5.1.1", - "sha.js": "2.4.8" - } - }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", - "dev": true - }, - "performance-now": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz", - "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=", - "dev": true - }, - "pify": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "pinkie": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-1.0.0.tgz", - "integrity": "sha1-Wkfyi6EBXQIBvae/DzWOR77Ix+Q=", - "dev": true - }, - "pinkie-promise": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-1.0.0.tgz", - "integrity": "sha1-0dpn9UglY7t89X8oauKCLs+/NnA=", - "dev": true, - "requires": { - "pinkie": "1.0.0" - } - }, - "pkg": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/pkg/-/pkg-4.1.4.tgz", - "integrity": "sha512-e/EhOaz4OEZyf4kw04+b98/mOwBj0DFlxgMHUqu/fyloD2b5WY13ZOGy6Xpl/dMeD7JjLcqYV/msYTlfOEaiqA==", - "dev": true, - "requires": { - "acorn": "5.1.1", - "babel-runtime": "6.25.0", - "chalk": "2.0.1", - "escodegen": "1.8.1", - "fs-extra": "4.0.0", - "globby": "6.1.0", - "in-publish": "2.0.0", - "minimist": "1.2.0", - "multistream": "2.1.0", - "pkg-fetch": "2.3.7", - "progress": "2.0.0", - "resolve": "1.4.0", - "simple-bufferstream": "1.0.0", - "stream-meter": "1.0.4" - } - }, - "pkg-conf": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.0.0.tgz", - "integrity": "sha1-BxyHZQQDvM+5xif1h1G/5HwGcnk=", - "dev": true, - "requires": { - "find-up": "2.1.0", - "load-json-file": "2.0.0" - } - }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "requires": { - "find-up": "2.1.0" - } - }, - "pkg-fetch": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/pkg-fetch/-/pkg-fetch-2.3.7.tgz", - "integrity": "sha512-xUyJ+9ZYAtBlkZWdiguXuL/isys+HnW4Zff5tMHR5qMg0wTbBvDvCpYkJKAhsVPN1Zo0fq2Z1JQ3xcPN6WZP7Q==", - "dev": true, - "requires": { - "babel-runtime": "6.23.0", - "byline": "5.0.0", - "chalk": "1.1.3", - "expand-template": "1.0.3", - "fs-extra": "3.0.1", - "in-publish": "2.0.0", - "minimist": "1.2.0", - "progress": "2.0.0", - "request": "2.81.0", - "request-progress": "3.0.0", - "semver": "5.3.0", - "unique-temp-dir": "1.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "babel-runtime": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.23.0.tgz", - "integrity": "sha1-CpSJ8UTecO+zzkMArM2zKeL8VDs=", - "dev": true, - "requires": { - "core-js": "2.4.1", - "regenerator-runtime": "0.10.5" - } - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, - "fs-extra": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-3.0.1.tgz", - "integrity": "sha1-N5TzeMWLNC6n27sjCVEJxLO2IpE=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "jsonfile": "3.0.1", - "universalify": "0.1.1" - } - }, - "semver": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", - "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", - "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", - "dev": true, - "requires": { - "find-up": "2.1.0" - } - }, - "plur": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/plur/-/plur-2.1.2.tgz", - "integrity": "sha1-dIJFLBoPUI4+NE6uwxLJHCncZVo=", - "dev": true, - "requires": { - "irregular-plurals": "1.3.0" - } - }, - "pluralize": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz", - "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=", - "dev": true - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true - }, - "prepend-http": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", - "dev": true - }, - "preserve": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", - "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", - "dev": true - }, - "prettier": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.5.3.tgz", - "integrity": "sha1-WdrcaDNF7GuI+IuU7Urn4do5S/4=", - "dev": true - }, - "pretty-ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-2.1.0.tgz", - "integrity": "sha1-QlfCVt8/sLRR1q/6qwIYhBJpgdw=", - "dev": true, - "requires": { - "is-finite": "1.0.2", - "parse-ms": "1.0.1", - "plur": "1.0.0" - }, - "dependencies": { - "plur": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/plur/-/plur-1.0.0.tgz", - "integrity": "sha1-24XGgU9eXlo7Se/CjWBP7GKXUVY=", - "dev": true - } - } - }, - "printf": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/printf/-/printf-0.2.5.tgz", - "integrity": "sha1-xDjKLKM+OSdnHbSracDlL5NqTw8=", - "dev": true - }, - "private": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.7.tgz", - "integrity": "sha1-aM5eih7woju1cMwoU3tTMqumPvE=", - "dev": true - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz", - "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M=", - "dev": true - }, - "progress": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", - "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", - "dev": true - }, - "proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=", - "dev": true - }, - "proto-props": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/proto-props/-/proto-props-0.2.1.tgz", - "integrity": "sha1-XgHcJnWg3pq/p255nfozTW9IP0s=", - "dev": true - }, - "prr": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz", - "integrity": "sha1-GoS4WQgyVQFBGFPQCB7j+obikmo=", - "dev": true - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "psl": { - "version": "1.1.19", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.19.tgz", - "integrity": "sha1-Zhe0FaNKgr9lgN5NDP1gA+PZQ8I=", - "dev": true - }, - "public-encrypt": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz", - "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=", - "dev": true, - "requires": { - "bn.js": "4.11.7", - "browserify-rsa": "4.0.1", - "create-hash": "1.1.3", - "parse-asn1": "5.1.0", - "randombytes": "2.0.5" - } - }, - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - }, - "qs": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz", - "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=", - "dev": true - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "randomatic": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz", - "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==", - "dev": true, - "requires": { - "is-number": "3.0.0", - "kind-of": "4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "3.2.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "1.1.5" - } - } - } - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "1.1.5" - } - } - } - }, - "randombytes": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.5.tgz", - "integrity": "sha512-8T7Zn1AhMsQ/HI1SjcCfT/t4ii3eAqco3yOcSzS4mozsOz69lHLsoMXmF9nZgnFanYscnSlUSgs8uZyKzpE6kg==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - }, - "rc": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.1.tgz", - "integrity": "sha1-LgPo5C7kULjLPc5lvhv4l04d/ZU=", - "dev": true, - "requires": { - "deep-extend": "0.4.2", - "ini": "1.3.4", - "minimist": "1.2.0", - "strip-json-comments": "2.0.1" - } - }, - "reach": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/reach/-/reach-1.0.0.tgz", - "integrity": "sha1-TRLRYJYLysZ9xiTw+Ruv6zb3lPY=", - "dev": true - }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "dev": true, - "requires": { - "load-json-file": "2.0.0", - "normalize-package-data": "2.4.0", - "path-type": "2.0.0" - } - }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "requires": { - "find-up": "2.1.0", - "read-pkg": "2.0.0" - } - }, - "readable-stream": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz", - "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==", - "dev": true, - "requires": { - "core-util-is": "1.0.2", - "inherits": "2.0.3", - "isarray": "1.0.0", - "process-nextick-args": "1.0.7", - "safe-buffer": "5.1.1", - "string_decoder": "1.0.3", - "util-deprecate": "1.0.2" - } - }, - "readdirp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", - "integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "minimatch": "3.0.4", - "readable-stream": "2.3.3", - "set-immediate-shim": "1.0.1" - } - }, - "readline2": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz", - "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=", - "dev": true, - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "mute-stream": "0.0.5" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, - "mute-stream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz", - "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA=", - "dev": true - } - } - }, - "rechoir": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", - "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", - "dev": true, - "requires": { - "resolve": "1.4.0" - } - }, - "redent": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", - "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", - "dev": true, - "requires": { - "indent-string": "2.1.0", - "strip-indent": "1.0.1" - }, - "dependencies": { - "indent-string": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz", - "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=", - "dev": true, - "requires": { - "repeating": "2.0.1" - } - } - } - }, - "regenerate": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.2.tgz", - "integrity": "sha1-0ZQcZ7rUN+G+dkM63Vs4X5WxkmA=", - "dev": true - }, - "regenerator-runtime": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", - "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=", - "dev": true - }, - "regenerator-transform": { - "version": "0.9.11", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.9.11.tgz", - "integrity": "sha1-On0GdSDLe3F2dp61/4aGkb7+EoM=", - "dev": true, - "requires": { - "babel-runtime": "6.25.0", - "babel-types": "6.25.0", - "private": "0.1.7" - } - }, - "regex-cache": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/regex-cache/-/regex-cache-0.4.3.tgz", - "integrity": "sha1-mxpsNdTQ3871cRrmUejp09cRQUU=", - "dev": true, - "requires": { - "is-equal-shallow": "0.1.3", - "is-primitive": "2.0.0" - } - }, - "regexpu-core": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", - "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", - "dev": true, - "requires": { - "regenerate": "1.3.2", - "regjsgen": "0.2.0", - "regjsparser": "0.1.5" - } - }, - "registry-auth-token": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.1.tgz", - "integrity": "sha1-+w0yie4Nmtosu1KvXf5mywcNMAY=", - "dev": true, - "requires": { - "rc": "1.2.1", - "safe-buffer": "5.1.1" - } - }, - "registry-url": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", - "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", - "dev": true, - "requires": { - "rc": "1.2.1" - } - }, - "regjsgen": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", - "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", - "dev": true - }, - "regjsparser": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", - "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", - "dev": true, - "requires": { - "jsesc": "0.5.0" - } - }, - "release-zalgo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", - "dev": true, - "requires": { - "es6-error": "4.0.2" - } - }, - "remove-trailing-separator": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.0.2.tgz", - "integrity": "sha1-abBi2XhyetFNxrVrpKt3L9jXBRE=", - "dev": true - }, - "repeat-element": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", - "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "dev": true, - "requires": { - "is-finite": "1.0.2" - } - }, - "request": { - "version": "2.81.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz", - "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=", - "dev": true, - "requires": { - "aws-sign2": "0.6.0", - "aws4": "1.6.0", - "caseless": "0.12.0", - "combined-stream": "1.0.5", - "extend": "3.0.1", - "forever-agent": "0.6.1", - "form-data": "2.1.4", - "har-validator": "4.2.1", - "hawk": "3.1.3", - "http-signature": "1.1.1", - "is-typedarray": "1.0.0", - "isstream": "0.1.2", - "json-stringify-safe": "5.0.1", - "mime-types": "2.1.16", - "oauth-sign": "0.8.2", - "performance-now": "0.2.0", - "qs": "6.4.0", - "safe-buffer": "5.1.1", - "stringstream": "0.0.5", - "tough-cookie": "2.3.2", - "tunnel-agent": "0.6.0", - "uuid": "3.1.0" - } - }, - "request-progress": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", - "integrity": "sha1-TKdUCBx/7GP1BeT6qCWqBs1mnb4=", - "dev": true, - "requires": { - "throttleit": "1.0.0" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-from-string": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-1.2.1.tgz", - "integrity": "sha1-UpyczvJzgK3+yaL5ZbZJu+5jZBg=", - "dev": true - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true - }, - "require-precompiled": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/require-precompiled/-/require-precompiled-0.1.0.tgz", - "integrity": "sha1-WhtS63Dr7UPrmC6XTIWrWVceVvo=", - "dev": true - }, - "require-uncached": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", - "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", - "dev": true, - "requires": { - "caller-path": "0.1.0", - "resolve-from": "1.0.1" - }, - "dependencies": { - "resolve-from": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", - "dev": true - } - } - }, - "resolve": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz", - "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==", - "dev": true, - "requires": { - "path-parse": "1.0.5" - } - }, - "resolve-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", - "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", - "dev": true, - "requires": { - "resolve-from": "3.0.0" - } - }, - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true - }, - "restore-cursor": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", - "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", - "dev": true, - "requires": { - "onetime": "2.0.1", - "signal-exit": "3.0.2" - } - }, - "resumer": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/resumer/-/resumer-0.0.0.tgz", - "integrity": "sha1-8ej0YeQGS6Oegq883CqMiT0HZ1k=", - "dev": true, - "requires": { - "through": "2.3.8" - } - }, - "retry": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz", - "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=", - "dev": true - }, - "right-align": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz", - "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=", - "dev": true, - "requires": { - "align-text": "0.1.4" - } - }, - "rimraf": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz", - "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=", - "dev": true, - "requires": { - "glob": "7.1.2" - } - }, - "ripemd160": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz", - "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=", - "dev": true, - "requires": { - "hash-base": "2.0.2", - "inherits": "2.0.3" - } - }, - "run-async": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", - "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", - "dev": true, - "requires": { - "is-promise": "2.1.0" - } - }, - "rx-lite": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", - "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", - "dev": true - }, - "rx-lite-aggregates": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", - "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", - "dev": true, - "requires": { - "rx-lite": "4.0.8" - } - }, - "rxjs": { - "version": "5.4.2", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.4.2.tgz", - "integrity": "sha1-KjI2/L8D31e64G/Wly/ZnlwI/Pc=", - "dev": true, - "requires": { - "symbol-observable": "1.0.4" - }, - "dependencies": { - "symbol-observable": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.4.tgz", - "integrity": "sha1-Kb9hXUqnEhvdiYsi1LP5vE4qoD0=", - "dev": true - } - } - }, - "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", - "dev": true - }, - "seek-bzip": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.5.tgz", - "integrity": "sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w=", - "dev": true, - "requires": { - "commander": "2.8.1" - } - }, - "semver": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", - "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", - "dev": true - }, - "semver-diff": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", - "integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=", - "dev": true, - "requires": { - "semver": "5.4.1" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", - "dev": true - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "sha.js": { - "version": "2.4.8", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.8.tgz", - "integrity": "sha1-NwaMLEdra69ALRSknGf1l5IfY08=", - "dev": true, - "requires": { - "inherits": "2.0.3" - } - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "shelljs": { - "version": "0.7.8", - "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.7.8.tgz", - "integrity": "sha1-3svPh0sNHl+3LhSxZKloMEjprLM=", - "dev": true, - "requires": { - "glob": "7.1.2", - "interpret": "1.0.3", - "rechoir": "0.6.2" - } - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, - "simple-bufferstream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/simple-bufferstream/-/simple-bufferstream-1.0.0.tgz", - "integrity": "sha1-XKsQ6FGqccZnt3th/hux2QpguqQ=", - "dev": true - }, - "single-line-log": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/single-line-log/-/single-line-log-1.1.2.tgz", - "integrity": "sha1-wvg/Jzo+GhbtsJlWYdoO1e8DM2Q=", - "dev": true, - "requires": { - "string-width": "1.0.2" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - } - } - }, - "slackup": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/slackup/-/slackup-2.0.1.tgz", - "integrity": "sha1-/WyHkZk3XLw35fX9qOcH8xdycDA=", - "dev": true, - "requires": { - "form-data": "2.1.4", - "node-fetch": "1.7.1" - } - }, - "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", - "dev": true - }, - "slice-ansi": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", - "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "2.0.0" - } - }, - "slide": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/slide/-/slide-1.1.6.tgz", - "integrity": "sha1-VusCfWW00tzmyy4tMsTUr8nh1wc=", - "dev": true - }, - "sntp": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz", - "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=", - "dev": true, - "requires": { - "hoek": "2.16.3" - } - }, - "socket.io-client": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-1.7.4.tgz", - "integrity": "sha1-7J+CA1btme9tNX8HVtZIcXvdQoE=", - "dev": true, - "requires": { - "backo2": "1.0.2", - "component-bind": "1.0.0", - "component-emitter": "1.2.1", - "debug": "2.3.3", - "engine.io-client": "1.8.4", - "has-binary": "0.1.7", - "indexof": "0.0.1", - "object-component": "0.0.3", - "parseuri": "0.0.5", - "socket.io-parser": "2.3.1", - "to-array": "0.1.4" - }, - "dependencies": { - "debug": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.3.3.tgz", - "integrity": "sha1-QMRT5n5uE8kB3ewxeviYbNqe/4w=", - "dev": true, - "requires": { - "ms": "0.7.2" - } - }, - "ms": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.2.tgz", - "integrity": "sha1-riXPJRKziFodldfwN4aNhDESR2U=", - "dev": true - } - } - }, - "socket.io-parser": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-2.3.1.tgz", - "integrity": "sha1-3VMgJRA85Clpcya+/WQAX8/ltKA=", - "dev": true, - "requires": { - "component-emitter": "1.1.2", - "debug": "2.2.0", - "isarray": "0.0.1", - "json3": "3.3.2" - }, - "dependencies": { - "component-emitter": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.1.2.tgz", - "integrity": "sha1-KWWU8nU9qmOZbSrwjRWpURbJrsM=", - "dev": true - }, - "debug": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz", - "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=", - "dev": true, - "requires": { - "ms": "0.7.1" - } - }, - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "ms": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz", - "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=", - "dev": true - } - } - }, - "sort-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-2.0.0.tgz", - "integrity": "sha1-ZYU1WEhh7JfXMNbPQYIuH1ZoQSg=", - "dev": true, - "requires": { - "is-plain-obj": "1.1.0" - } - }, - "sort-keys-length": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz", - "integrity": "sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg=", - "dev": true, - "requires": { - "sort-keys": "1.1.2" - }, - "dependencies": { - "sort-keys": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", - "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", - "dev": true, - "requires": { - "is-plain-obj": "1.1.0" - } - } - } - }, - "source-list-map": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz", - "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==", - "dev": true - }, - "source-map": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz", - "integrity": "sha1-dc449SvwczxafwwRjYEzSiu19BI=", - "dev": true - }, - "source-map-support": { - "version": "0.4.15", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.15.tgz", - "integrity": "sha1-AyAt9lwG0r2MfsI2KhkwVv7407E=", - "dev": true, - "requires": { - "source-map": "0.5.6" - } - }, - "spdx-correct": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz", - "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=", - "dev": true, - "requires": { - "spdx-license-ids": "1.2.2" - } - }, - "spdx-expression-parse": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz", - "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw=", - "dev": true - }, - "spdx-license-ids": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz", - "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc=", - "dev": true - }, - "split-array": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/split-array/-/split-array-1.0.1.tgz", - "integrity": "sha1-fQwQNmcF86pGIFKat1W/ftIiDaE=", - "dev": true - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "sshpk": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz", - "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=", - "dev": true, - "requires": { - "asn1": "0.2.3", - "assert-plus": "1.0.0", - "bcrypt-pbkdf": "1.0.1", - "dashdash": "1.14.1", - "ecc-jsbn": "0.1.1", - "getpass": "0.1.7", - "jsbn": "0.1.1", - "tweetnacl": "0.14.5" - }, - "dependencies": { - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", - "dev": true - } - } - }, - "stack-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.1.tgz", - "integrity": "sha1-1PM6tU6OOHeLDKXP07OvsS22hiA=", - "dev": true - }, - "staged-git-files": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/staged-git-files/-/staged-git-files-0.0.4.tgz", - "integrity": "sha1-15fhtVHKemOd7AI33G60u5vhfTU=", - "dev": true - }, - "stream-browserify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.1.tgz", - "integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=", - "dev": true, - "requires": { - "inherits": "2.0.3", - "readable-stream": "2.3.3" - } - }, - "stream-http": { - "version": "2.7.2", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.7.2.tgz", - "integrity": "sha512-c0yTD2rbQzXtSsFSVhtpvY/vS6u066PcXOX9kBB3mSO76RiUQzL340uJkGBWnlBg4/HZzqiUXtaVA7wcRcJgEw==", - "dev": true, - "requires": { - "builtin-status-codes": "3.0.0", - "inherits": "2.0.3", - "readable-stream": "2.3.3", - "to-arraybuffer": "1.0.1", - "xtend": "4.0.1" - } - }, - "stream-meter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/stream-meter/-/stream-meter-1.0.4.tgz", - "integrity": "sha1-Uq+Vql6nYKJJFxZwTb/5D3Ov3R0=", - "dev": true, - "requires": { - "readable-stream": "2.3.3" - } - }, - "stream-to-observable": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/stream-to-observable/-/stream-to-observable-0.1.0.tgz", - "integrity": "sha1-Rb8dny19wJvtgfHDB8Qw5ouEz/4=", - "dev": true - }, - "string_decoder": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz", - "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "2.0.0", - "strip-ansi": "4.0.0" - } - }, - "stringstream": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz", - "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg=", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "3.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "strip-bom-buf": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-bom-buf/-/strip-bom-buf-1.0.0.tgz", - "integrity": "sha1-HLRar1dTD0yvhsf3UXnSyaUd1XI=", - "dev": true, - "requires": { - "is-utf8": "0.2.1" - } - }, - "strip-dirs": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.0.0.tgz", - "integrity": "sha1-YQzbKSggDaAAT0HcuQ/JXNkZoLY=", - "dev": true, - "requires": { - "is-natural-number": "4.0.1" - } - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, - "strip-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", - "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", - "dev": true, - "requires": { - "get-stdin": "4.0.1" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "strip-outer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-1.0.0.tgz", - "integrity": "sha1-qsC6YNLpDF1PJ1/Yhp/ZotMQ/7g=", - "dev": true, - "requires": { - "escape-string-regexp": "1.0.5" - } - }, - "stripe": { - "version": "4.23.1", - "resolved": "https://registry.npmjs.org/stripe/-/stripe-4.23.1.tgz", - "integrity": "sha1-31KXcyPT7oh6B6xZBXA/zcBF0u4=", - "dev": true, - "requires": { - "bluebird": "2.11.0", - "lodash.isplainobject": "4.0.6", - "object-assign": "4.1.1", - "qs": "6.0.4" - }, - "dependencies": { - "bluebird": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz", - "integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=", - "dev": true - }, - "qs": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.0.4.tgz", - "integrity": "sha1-UQGdhHIMk5uCc36EVWp4Izjs6ns=", - "dev": true - } - } - }, - "supports-color": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.2.1.tgz", - "integrity": "sha512-qxzYsob3yv6U+xMzPrv170y8AwGP7i74g+pbixCfD6rgso8BscLT2qXIuz6TpOaiJZ3mFgT5O9lyT9nMU4LfaA==", - "dev": true, - "requires": { - "has-flag": "2.0.0" - } - }, - "symbol-observable": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-0.2.4.tgz", - "integrity": "sha1-lag9smGG1q9+ehjb2XYKL4bQj0A=", - "dev": true - }, - "table": { - "version": "3.8.3", - "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz", - "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=", - "dev": true, - "requires": { - "ajv": "4.11.8", - "ajv-keywords": "1.5.1", - "chalk": "1.1.3", - "lodash": "4.17.4", - "slice-ansi": "0.0.4", - "string-width": "2.1.1" - }, - "dependencies": { - "ajv-keywords": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz", - "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, - "slice-ansi": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", - "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", - "dev": true - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "tapable": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.2.7.tgz", - "integrity": "sha1-5GwNqsuyuKmLmwzqD0BSEFgX7Vw=", - "dev": true - }, - "tar-stream": { - "version": "1.5.4", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.4.tgz", - "integrity": "sha1-NlSc8E7RrumyowwBQyUiONr5QBY=", - "dev": true, - "requires": { - "bl": "1.2.1", - "end-of-stream": "1.4.0", - "readable-stream": "2.3.3", - "xtend": "4.0.1" - } - }, - "term-size": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", - "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", - "dev": true, - "requires": { - "execa": "0.7.0" - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "the-argv": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/the-argv/-/the-argv-1.0.0.tgz", - "integrity": "sha1-AIRwUAVzDdhNt1UlPJMa45jblSI=", - "dev": true - }, - "throttleit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", - "integrity": "sha1-nnhYNtr0Z0MUWlmEtiaNgoUorGw=", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "through2": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", - "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", - "dev": true, - "requires": { - "readable-stream": "2.3.3", - "xtend": "4.0.1" - } - }, - "time-require": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/time-require/-/time-require-0.1.2.tgz", - "integrity": "sha1-+eEss3D8JgXhFARYK6VO9corLZg=", - "dev": true, - "requires": { - "chalk": "0.4.0", - "date-time": "0.1.1", - "pretty-ms": "0.2.2", - "text-table": "0.2.0" - }, - "dependencies": { - "ansi-styles": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz", - "integrity": "sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=", - "dev": true - }, - "chalk": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz", - "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=", - "dev": true, - "requires": { - "ansi-styles": "1.0.0", - "has-color": "0.1.7", - "strip-ansi": "0.1.1" - } - }, - "date-time": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/date-time/-/date-time-0.1.1.tgz", - "integrity": "sha1-7S9tk9l5DOL9ZtW1/z7dW7y/Owc=", - "dev": true - }, - "parse-ms": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-0.1.2.tgz", - "integrity": "sha1-3T+iXtbC78e93hKtm0bBY6opIk4=", - "dev": true - }, - "pretty-ms": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-0.2.2.tgz", - "integrity": "sha1-2oeaaC/zOjcBEEbxPWJ/Z8c7hPY=", - "dev": true, - "requires": { - "parse-ms": "0.1.2" - } - }, - "strip-ansi": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz", - "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=", - "dev": true - } - } - }, - "time-zone": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/time-zone/-/time-zone-1.0.0.tgz", - "integrity": "sha1-mcW/VZWJZq9tBtg73zgA3IL67F0=", - "dev": true - }, - "timed-out": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/timed-out/-/timed-out-4.0.1.tgz", - "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", - "dev": true - }, - "timers-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.2.tgz", - "integrity": "sha1-q0iDz1l9zVCvIRNJoA+8pWrIa4Y=", - "dev": true, - "requires": { - "setimmediate": "1.0.5" - } - }, - "tmp": { - "version": "0.0.31", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", - "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", - "dev": true, - "requires": { - "os-tmpdir": "1.0.2" - } - }, - "tmp-promise": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-1.0.3.tgz", - "integrity": "sha1-O0UJJ6t4xq7cpeYoxnf1Nsrji8U=", - "dev": true, - "requires": { - "bluebird": "3.5.0", - "tmp": "0.0.31" - } - }, - "to-array": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz", - "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA=", - "dev": true - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=", - "dev": true - }, - "tough-cookie": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.2.tgz", - "integrity": "sha1-8IH3bkyFcg5sN6X6ztc3FQ2EByo=", - "dev": true, - "requires": { - "punycode": "1.4.1" - } - }, - "trim-newlines": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", - "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", - "dev": true - }, - "trim-off-newlines": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz", - "integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=", - "dev": true - }, - "trim-repeated": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-1.0.0.tgz", - "integrity": "sha1-42RqLqTokTEr9+rObPsFOAvAHCE=", - "dev": true, - "requires": { - "escape-string-regexp": "1.0.5" - } - }, - "trim-right": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", - "dev": true - }, - "tryit": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz", - "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics=", - "dev": true - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=", - "dev": true, - "requires": { - "safe-buffer": "5.1.1" - } - }, - "tweetnacl": { - "version": "0.14.5", - "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", - "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true, - "optional": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "1.1.2" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "uglify-js": { - "version": "2.8.29", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz", - "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=", - "dev": true, - "requires": { - "source-map": "0.5.6", - "uglify-to-browserify": "1.0.2", - "yargs": "3.10.0" - }, - "dependencies": { - "camelcase": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz", - "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=", - "dev": true - }, - "yargs": { - "version": "3.10.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", - "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", - "dev": true, - "requires": { - "camelcase": "1.2.1", - "cliui": "2.1.0", - "decamelize": "1.2.0", - "window-size": "0.1.0" - } - } - } - }, - "uglify-to-browserify": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz", - "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=", - "dev": true, - "optional": true - }, - "uglifyjs-webpack-plugin": { - "version": "0.4.6", - "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-0.4.6.tgz", - "integrity": "sha1-uVH0q7a9YX5m9j64kUmOORdj4wk=", - "dev": true, - "requires": { - "source-map": "0.5.6", - "uglify-js": "2.8.29", - "webpack-sources": "1.0.1" - } - }, - "uid2": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz", - "integrity": "sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I=", - "dev": true - }, - "ultron": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.0.2.tgz", - "integrity": "sha1-rOEWq1V80Zc4ak6I9GhTeMiy5Po=", - "dev": true - }, - "unbzip2-stream": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.2.5.tgz", - "integrity": "sha512-izD3jxT8xkzwtXRUZjtmRwKnZoeECrfZ8ra/ketwOcusbZEp4mjULMnJOCfTDZBgGQAAY1AJ/IgxcwkavcX9Og==", - "dev": true, - "requires": { - "buffer": "3.6.0", - "through": "2.3.8" - } - }, - "unique-string": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unique-string/-/unique-string-1.0.0.tgz", - "integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=", - "dev": true, - "requires": { - "crypto-random-string": "1.0.0" - } - }, - "unique-temp-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unique-temp-dir/-/unique-temp-dir-1.0.0.tgz", - "integrity": "sha1-bc6VsmgcoAPuv7MEpBX5y6vMU4U=", - "dev": true, - "requires": { - "mkdirp": "0.5.1", - "os-tmpdir": "1.0.2", - "uid2": "0.0.3" - } - }, - "universalify": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz", - "integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=", - "dev": true - }, - "unzip-response": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz", - "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=", - "dev": true - }, - "update-notifier": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.2.0.tgz", - "integrity": "sha1-G1g3z5DAc22IYncytmHBOPht5y8=", - "dev": true, - "requires": { - "boxen": "1.2.1", - "chalk": "1.1.3", - "configstore": "3.1.1", - "import-lazy": "2.1.0", - "is-npm": "1.0.0", - "latest-version": "3.1.0", - "semver-diff": "2.1.0", - "xdg-basedir": "3.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", - "dev": true - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "dev": true, - "requires": { - "ansi-styles": "2.2.1", - "escape-string-regexp": "1.0.5", - "has-ansi": "2.0.0", - "strip-ansi": "3.0.1", - "supports-color": "2.0.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", - "dev": true - } - } - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "url-parse-lax": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", - "integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=", - "dev": true, - "requires": { - "prepend-http": "1.0.4" - } - }, - "url-to-options": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/url-to-options/-/url-to-options-1.0.1.tgz", - "integrity": "sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k=", - "dev": true - }, - "user-home": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz", - "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=", - "dev": true, - "requires": { - "os-homedir": "1.0.2" - } - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "uuid": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.1.0.tgz", - "integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g==", - "dev": true - }, - "validate-npm-package-license": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz", - "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=", - "dev": true, - "requires": { - "spdx-correct": "1.0.2", - "spdx-expression-parse": "1.0.4" - } - }, - "verror": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.3.6.tgz", - "integrity": "sha1-z/XfEpRtKX0rqu+qJoniW+AcAFw=", - "dev": true, - "requires": { - "extsprintf": "1.0.2" - } - }, - "vm-browserify": { - "version": "0.0.4", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", - "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", - "dev": true, - "requires": { - "indexof": "0.0.1" - } - }, - "watchpack": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.4.0.tgz", - "integrity": "sha1-ShRyvLuVK9Cpu0A2gB+VTfs5+qw=", - "dev": true, - "requires": { - "async": "2.5.0", - "chokidar": "1.7.0", - "graceful-fs": "4.1.11" - } - }, - "webpack": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.4.1.tgz", - "integrity": "sha1-TD9PP7MYFVpNsMtqNv8FxWl0GPQ=", - "dev": true, - "requires": { - "acorn": "5.1.1", - "acorn-dynamic-import": "2.0.2", - "ajv": "5.2.2", - "ajv-keywords": "2.1.0", - "async": "2.5.0", - "enhanced-resolve": "3.4.1", - "escope": "3.6.0", - "interpret": "1.0.3", - "json-loader": "0.5.7", - "json5": "0.5.1", - "loader-runner": "2.3.0", - "loader-utils": "1.1.0", - "memory-fs": "0.4.1", - "mkdirp": "0.5.1", - "node-libs-browser": "2.0.0", - "source-map": "0.5.6", - "supports-color": "4.2.1", - "tapable": "0.2.7", - "uglifyjs-webpack-plugin": "0.4.6", - "watchpack": "1.4.0", - "webpack-sources": "1.0.1", - "yargs": "8.0.2" - }, - "dependencies": { - "ajv": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.2.2.tgz", - "integrity": "sha1-R8aNaehvXZUxA7AHSpQw3GPaXjk=", - "dev": true, - "requires": { - "co": "4.6.0", - "fast-deep-equal": "1.0.0", - "json-schema-traverse": "0.3.1", - "json-stable-stringify": "1.0.1" - } - } - } - }, - "webpack-sources": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.0.1.tgz", - "integrity": "sha512-05tMxipUCwHqYaVS8xc7sYPTly8PzXayRCB4dTxLhWTqlKUiwH6ezmEe0OSreL1c30LAuA3Zqmc+uEBUGFJDjw==", - "dev": true, - "requires": { - "source-list-map": "2.0.0", - "source-map": "0.5.6" - } - }, - "well-known-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/well-known-symbols/-/well-known-symbols-1.0.0.tgz", - "integrity": "sha1-c8eK6Bp3Jqj6WY4ogIAcixYiVRg=", - "dev": true - }, - "which": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", - "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", - "dev": true, - "requires": { - "isexe": "2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "widest-line": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-1.0.0.tgz", - "integrity": "sha1-DAnIXCqUaD0Nfq+O4JfVZL8OEFw=", - "dev": true, - "requires": { - "string-width": "1.0.2" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - } - } - }, - "window-size": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz", - "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=", - "dev": true - }, - "wordwrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", - "dev": true - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, - "requires": { - "string-width": "1.0.2", - "strip-ansi": "3.0.1" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", - "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", - "dev": true, - "requires": { - "mkdirp": "0.5.1" - } - }, - "write-file-atomic": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.1.0.tgz", - "integrity": "sha512-0TZ20a+xcIl4u0+Mj5xDH2yOWdmQiXlKf9Hm+TgDXjTMsEYb+gDrmb8e8UNAzMCitX8NBqG4Z/FUQIyzv/R1JQ==", - "dev": true, - "requires": { - "graceful-fs": "4.1.11", - "imurmurhash": "0.1.4", - "slide": "1.1.6" - } - }, - "write-json-file": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/write-json-file/-/write-json-file-2.2.0.tgz", - "integrity": "sha1-UYYlBruzthnu+reFnx/WxtBTCHY=", - "dev": true, - "requires": { - "detect-indent": "5.0.0", - "graceful-fs": "4.1.11", - "make-dir": "1.0.0", - "pify": "2.3.0", - "sort-keys": "1.1.2", - "write-file-atomic": "2.1.0" - }, - "dependencies": { - "detect-indent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", - "integrity": "sha1-OHHMCmoALow+Wzz38zYmRnXwa50=", - "dev": true - }, - "sort-keys": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", - "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", - "dev": true, - "requires": { - "is-plain-obj": "1.1.0" - } - } - } - }, - "write-pkg": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/write-pkg/-/write-pkg-3.1.0.tgz", - "integrity": "sha1-AwqZlMyZk9JbTnWp8aGSNgcpHOk=", - "dev": true, - "requires": { - "sort-keys": "2.0.0", - "write-json-file": "2.2.0" - } - }, - "ws": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/ws/-/ws-1.1.2.tgz", - "integrity": "sha1-iiRPoFJAHgjJiGz0SoUYnh/UBn8=", - "dev": true, - "requires": { - "options": "0.0.6", - "ultron": "1.0.2" - } - }, - "wtf-8": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/wtf-8/-/wtf-8-1.0.0.tgz", - "integrity": "sha1-OS2LotDxw00e4tYw8V0O+2jhBIo=", - "dev": true - }, - "xdg-basedir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-3.0.0.tgz", - "integrity": "sha1-SWsswQnsqNus/i3HK2A8F8WHCtQ=", - "dev": true - }, - "xmlhttprequest-ssl": { - "version": "1.5.3", - "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.3.tgz", - "integrity": "sha1-GFqIjATspGw+QHDZn3tJ3jUomS0=", - "dev": true - }, - "xo": { - "version": "0.18.2", - "resolved": "https://registry.npmjs.org/xo/-/xo-0.18.2.tgz", - "integrity": "sha1-kqQusCpPsUnf6lUYAhkU9arIT/A=", - "dev": true, - "requires": { - "arrify": "1.0.1", - "debug": "2.6.8", - "deep-assign": "1.0.0", - "eslint": "3.19.0", - "eslint-config-xo": "0.18.2", - "eslint-formatter-pretty": "1.1.0", - "eslint-plugin-ava": "4.2.1", - "eslint-plugin-import": "2.7.0", - "eslint-plugin-no-use-extend-native": "0.3.12", - "eslint-plugin-promise": "3.5.0", - "eslint-plugin-unicorn": "2.1.2", - "get-stdin": "5.0.1", - "globby": "6.1.0", - "has-flag": "2.0.0", - "ignore": "3.3.3", - "lodash.isequal": "4.5.0", - "meow": "3.7.0", - "multimatch": "2.1.0", - "path-exists": "3.0.0", - "pkg-conf": "2.0.0", - "resolve-cwd": "1.0.0", - "resolve-from": "2.0.0", - "slash": "1.0.0", - "update-notifier": "2.2.0", - "xo-init": "0.5.0" - }, - "dependencies": { - "get-stdin": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz", - "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=", - "dev": true - }, - "resolve-cwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-1.0.0.tgz", - "integrity": "sha1-Tq7qQe0EDRcCRX32SkKysH0kb58=", - "dev": true, - "requires": { - "resolve-from": "2.0.0" - } - }, - "resolve-from": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz", - "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c=", - "dev": true - } - } - }, - "xo-init": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/xo-init/-/xo-init-0.5.0.tgz", - "integrity": "sha1-jijex5Z2zF4EL95f2PcQ4mRrDjY=", - "dev": true, - "requires": { - "arrify": "1.0.1", - "execa": "0.5.1", - "minimist": "1.2.0", - "path-exists": "3.0.0", - "read-pkg-up": "2.0.0", - "the-argv": "1.0.0", - "write-pkg": "2.1.0" - }, - "dependencies": { - "cross-spawn": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz", - "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=", - "dev": true, - "requires": { - "lru-cache": "4.1.1", - "which": "1.3.0" - } - }, - "execa": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.5.1.tgz", - "integrity": "sha1-3j+4XLjW6RyFvLzrFkWBeFy1ezY=", - "dev": true, - "requires": { - "cross-spawn": "4.0.2", - "get-stream": "2.3.1", - "is-stream": "1.1.0", - "npm-run-path": "2.0.2", - "p-finally": "1.0.0", - "signal-exit": "3.0.2", - "strip-eof": "1.0.0" - } - }, - "get-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", - "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", - "dev": true, - "requires": { - "object-assign": "4.1.1", - "pinkie-promise": "2.0.1" - } - }, - "pinkie": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true - }, - "pinkie-promise": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", - "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, - "requires": { - "pinkie": "2.0.4" - } - }, - "sort-keys": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", - "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", - "dev": true, - "requires": { - "is-plain-obj": "1.1.0" - } - }, - "write-pkg": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/write-pkg/-/write-pkg-2.1.0.tgz", - "integrity": "sha1-NTqkTDnEjCFED1wIzmq9RhQcnAg=", - "dev": true, - "requires": { - "sort-keys": "1.1.2", - "write-json-file": "2.2.0" - } - } - } - }, - "xtend": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", - "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", - "dev": true - }, - "y18n": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - }, - "yargs": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-8.0.2.tgz", - "integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=", - "dev": true, - "requires": { - "camelcase": "4.1.0", - "cliui": "3.2.0", - "decamelize": "1.2.0", - "get-caller-file": "1.0.2", - "os-locale": "2.1.0", - "read-pkg-up": "2.0.0", - "require-directory": "2.1.1", - "require-main-filename": "1.0.1", - "set-blocking": "2.0.0", - "string-width": "2.1.1", - "which-module": "2.0.0", - "y18n": "3.2.1", - "yargs-parser": "7.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true - }, - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - }, - "cliui": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", - "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, - "requires": { - "string-width": "1.0.2", - "strip-ansi": "3.0.1", - "wrap-ansi": "2.1.0" - }, - "dependencies": { - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "1.1.0", - "is-fullwidth-code-point": "1.0.0", - "strip-ansi": "3.0.1" - } - } - } - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "1.0.1" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "dev": true, - "requires": { - "ansi-regex": "2.1.1" - } - } - } - }, - "yargs-parser": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", - "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", - "dev": true, - "requires": { - "camelcase": "4.1.0" - }, - "dependencies": { - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - } - } - }, - "yauzl": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.8.0.tgz", - "integrity": "sha1-eUUK/yKyqcWkHvVOAtuQfM+/nuI=", - "dev": true, - "requires": { - "buffer-crc32": "0.2.13", - "fd-slicer": "1.0.1" - } - }, - "yeast": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz", - "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk=", - "dev": true - } - } -} diff --git a/package.json b/package.json deleted file mode 100644 index 8cedfaa..0000000 --- a/package.json +++ /dev/null @@ -1,124 +0,0 @@ -{ - "name": "now", - "version": "7.4.0", - "description": "The command line interface for Now", - "repository": "zeit/now-cli", - "license": "MIT", - "scripts": { - "postinstall": "node download/install.js", - "precommit": "xo --quiet && lint-staged", - "prepublish": "in-install || (npm run webpack && cp /dev/null download/dist/now)", - "link": "cd link && npm link", - "lint": "xo --quiet", - "test": "npm run lint && ava", - "pack": "pkg bin/now.js -c package.json -o packed/now", - "webpack": "webpack --context download --config download/webpack.js", - "clean": "rm -rf node_modules link/node_modules download/dist", - "prettify": "prettier --single-quote --no-semi --write `find ./lib -name '*.js'` `find ./bin -name '*.js'`" - }, - "pkg": { - "scripts": [ - "bin/*", - "lib/**/*" - ], - "targets": [ - "node7-alpine-x64", - "node7-linux-x64", - "node7-macos-x64", - "node7-win-x64" - ] - }, - "bin": { - "now": "download/dist/now" - }, - "files": [ - "download/dist", - "download/install.js" - ], - "ava": { - "failFast": true, - "files": [ - "test/*.js" - ] - }, - "xo": { - "ignores": [ - "test/_fixtures/**" - ], - "extends": "prettier" - }, - "lint-staged": { - "*.js": [ - "npm run lint", - "prettier --single-quote --no-semi --write", - "git add" - ] - }, - "greenkeeper": { - "ignore": [ - "socket.io-client" - ] - }, - "devDependencies": { - "@google/maps": "0.4.3", - "alpha-sort": "2.0.1", - "ansi-escapes": "2.0.0", - "ansi-regex": "3.0.0", - "arr-flatten": "1.1.0", - "array-unique": "0.3.2", - "async-retry": "1.1.3", - "ava": "0.21.0", - "babel-core": "6.25.0", - "babel-loader": "7.1.1", - "babel-plugin-transform-async-to-generator": "6.24.1", - "babel-plugin-transform-runtime": "6.23.0", - "babel-preset-es2015": "6.24.1", - "bytes": "2.5.0", - "chalk": "2.0.1", - "clipboardy": "1.1.4", - "credit-card": "3.0.1", - "cross-spawn": "5.1.0", - "dateformat": "2.0.0", - "death": "1.1.0", - "deployment-type": "1.0.1", - "docker-file-parser": "1.0.2", - "dotenv": "4.0.0", - "download": "6.2.5", - "email-prompt": "0.3.1", - "email-validator": "1.0.7", - "epipebomb": "1.0.0", - "eslint-config-prettier": "2.3.0", - "fs-extra": "4.0.0", - "glob": "7.1.2", - "ignore": "3.3.3", - "in-publish": "2.0.0", - "ini": "1.3.4", - "inquirer": "3.2.1", - "is-url": "1.2.2", - "lint-staged": "4.0.2", - "lodash.range": "3.2.0", - "minimist": "1.2.0", - "ms": "2.0.0", - "node-fetch": "1.7.1", - "ora": "1.3.0", - "pkg": "4.1.4", - "prettier": "1.5.3", - "printf": "0.2.5", - "progress": "2.0.0", - "psl": "1.1.19", - "resumer": "0.0.0", - "single-line-log": "1.1.2", - "slackup": "2.0.1", - "socket.io-client": "1.7.4", - "split-array": "1.0.1", - "strip-ansi": "4.0.0", - "stripe": "4.23.1", - "supports-color": "4.2.1", - "text-table": "0.2.0", - "tmp-promise": "1.0.3", - "update-notifier": "2.2.0", - "webpack": "3.4.1", - "which": "1.3.0", - "xo": "0.18.2" - } -} diff --git a/readme.md b/readme.md deleted file mode 100644 index 4d85e6f..0000000 --- a/readme.md +++ /dev/null @@ -1,42 +0,0 @@ -# now CLI - -[![Build Status](https://circleci.com/gh/zeit/now-cli.svg?style=shield)](https://circleci.com/gh/zeit/now-cli) -[![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/sindresorhus/xo) -[![Slack Channel](http://zeit-slackin.now.sh/badge.svg)](https://zeit.chat) - -This is the command line interface for [now](https://zeit.co/now): Realtime global deployments served over HTTP/2. - -It's also a special kind of package. When you install it using `npm install -g now`, it will automatically select the latest version of the [pkg](https://github.com/zeit/pkg)-ed `now` binary from [here](https://github.com/zeit/now-cli/releases) and place it on your device. - -## Usage - -Simply follow [this guide](https://zeit.co/download#command-line)! Then run this command to see a list of all commands: - -```bash -now help -``` - -## Why Ship a `pkg`-ed Binary? - -- Simpler installation for non-Node users like those deploying [static files](https://zeit.co/blog/unlimited-static) or [Dockerfiles](https://zeit.co/blog/now-dockerfile). -- Consistency across platforms and installation mechanisms (`npm`, `brew` and manual scripts) -- Parsing and evaluation optimizations lead to a faster bootup time -- Easier installation in automation environments (like CI systems) -- Increased safety by providing a unified signature mechanism for releases -- We're able to select our own Node version of choice and can take advantage of the latest features - -## Caught a Bug? - -1. [Fork](https://help.github.com/articles/fork-a-repo/) this repository to your own GitHub account and then [clone](https://help.github.com/articles/cloning-a-repository/) it to your local device -2. Link the package to the global module directory: `npm run link` (not `npm link`) -3. You can now start using `now` from the command line! - -As always, you can use `npm test` to run the tests and see if your changes have broken anything. - -## Authors - -- Guillermo Rauch ([@rauchg](https://twitter.com/rauchg)) - [▲ZEIT](https://zeit.co) -- Leo Lamprecht ([@notquiteleo](https://twitter.com/notquiteleo)) - [▲ZEIT](https://zeit.co) -- Tony Kovanen ([@TonyKovanen](https://twitter.com/TonyKovanen)) - [▲ZEIT](https://zeit.co) -- Olli Vanhoja ([@OVanhoja](https://twitter.com/OVanhoja)) - [▲ZEIT](https://zeit.co) -- Naoyuki Kanezawa ([@nkzawa](https://twitter.com/nkzawa)) - [▲ZEIT](https://zeit.co) diff --git a/scripts/slack.js b/scripts/slack.js deleted file mode 100755 index a0db958..0000000 --- a/scripts/slack.js +++ /dev/null @@ -1,70 +0,0 @@ -#!/usr/bin/env node - -const slackup = require('slackup') -const fetch = require('node-fetch') - -const { CIRCLE_PROJECT_USERNAME, CIRCLE_PROJECT_REPONAME } = process.env - -const repo = CIRCLE_PROJECT_USERNAME + '/' + CIRCLE_PROJECT_REPONAME -const commit = process.env.CIRCLE_SHA1 -const branch = process.env.CIRCLE_BRANCH -const apiKey = process.env.SLACK_TOKEN -const channel = process.env.SLACK_CHANNEL -const githubToken = process.env.GITHUB_TOKEN - -// Skip if not on a zeit repo -if (!/^zeit\//.test(repo)) { - console.log('not a zeit repo') - process.exit(0) -} - -if (!apiKey) { - console.log('$SLACKUP_TOKEN not found') - process.exit(0) -} - -if (!channel) { - console.log('$SLACKUP_CHANNEL not found') - process.exit(0) -} - -if (!githubToken) { - console.log('$GITHUB_TOKEN not found') - process.exit(0) -} - -const opts = { - headers: { - authorization: `token ${githubToken}` - } -} - -fetch(`https://api.github.com/repos/${repo}/commits/${commit}`, opts) - .then(res => res.json()) - .then(res => ({ - message: res.commit.message, - authorName: res.commit.author.name, - authorUrl: res.author.html_url - })) - .then(async res => { - const message = `:package: Here are the binaries for the branch *${branch}* of *${repo}* (commit by <${res.authorUrl}|${res.authorName}>):` - - const binaries = [ - `${__dirname}/../packed/now-macos`, - `${__dirname}/../packed/now-linux`, - `${__dirname}/../packed/now-win.exe` - ] - - try { - await slackup({ apiKey, channel, type: 'message', message }) - await slackup({ apiKey, channel, type: 'file', filePath: binaries[0] }) - await slackup({ apiKey, channel, type: 'file', filePath: binaries[1] }) - await slackup({ apiKey, channel, type: 'file', filePath: binaries[2] }) - } catch (err) { - console.log(`Couldn't send messages/files to Slack`, err) - } - }) - .catch(console.error) diff --git a/test/_fixtures/big-file/big.js b/test/_fixtures/big-file/big.js deleted file mode 100644 index 822f345..0000000 --- a/test/_fixtures/big-file/big.js +++ /dev/null @@ -1,49 +0,0 @@ -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot diff --git a/test/_fixtures/big-file/package.json b/test/_fixtures/big-file/package.json deleted file mode 100644 index 6c8ffab..0000000 --- a/test/_fixtures/big-file/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "", - "version": "0.0.1", - "description": "", - "dependencies": {} -} diff --git a/test/_fixtures/big-file/small-two.js b/test/_fixtures/big-file/small-two.js deleted file mode 100644 index cb190f3..0000000 --- a/test/_fixtures/big-file/small-two.js +++ /dev/null @@ -1,14 +0,0 @@ -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot -woot diff --git a/test/_fixtures/big-file/small.js b/test/_fixtures/big-file/small.js deleted file mode 100644 index 96b3774..0000000 --- a/test/_fixtures/big-file/small.js +++ /dev/null @@ -1 +0,0 @@ -woot diff --git a/test/_fixtures/directory-main/a/index.js b/test/_fixtures/directory-main/a/index.js deleted file mode 100644 index e69de29..0000000 diff --git a/test/_fixtures/directory-main/build/a.js b/test/_fixtures/directory-main/build/a.js deleted file mode 100644 index e69de29..0000000 diff --git a/test/_fixtures/directory-main/package.json b/test/_fixtures/directory-main/package.json deleted file mode 100644 index acca41d..0000000 --- a/test/_fixtures/directory-main/package.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "directory-main", - "version": "0.0.1", - "description": "", - "main": "./a", - "dependencies": {} -} diff --git a/test/_fixtures/dockerfile/Dockerfile b/test/_fixtures/dockerfile/Dockerfile deleted file mode 100644 index a86da2e..0000000 --- a/test/_fixtures/dockerfile/Dockerfile +++ /dev/null @@ -1 +0,0 @@ -CMD echo 'world' diff --git a/test/_fixtures/dockerfile/a.js b/test/_fixtures/dockerfile/a.js deleted file mode 100644 index ce49d09..0000000 --- a/test/_fixtures/dockerfile/a.js +++ /dev/null @@ -1 +0,0 @@ -// this should be included diff --git a/test/_fixtures/extensionless-main/build/a.js b/test/_fixtures/extensionless-main/build/a.js deleted file mode 100644 index e69de29..0000000 diff --git a/test/_fixtures/extensionless-main/index.js b/test/_fixtures/extensionless-main/index.js deleted file mode 100644 index e69de29..0000000 diff --git a/test/_fixtures/extensionless-main/package.json b/test/_fixtures/extensionless-main/package.json deleted file mode 100644 index 7d093bb..0000000 --- a/test/_fixtures/extensionless-main/package.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "extensionless-main", - "version": "0.0.1", - "description": "", - "main": "./index", - "dependencies": {} -} diff --git a/test/_fixtures/files-in-package-ignore/.a.swp b/test/_fixtures/files-in-package-ignore/.a.swp deleted file mode 100644 index e69de29..0000000 diff --git a/test/_fixtures/files-in-package-ignore/.npmignore b/test/_fixtures/files-in-package-ignore/.npmignore deleted file mode 100644 index cec0cb5..0000000 --- a/test/_fixtures/files-in-package-ignore/.npmignore +++ /dev/null @@ -1,2 +0,0 @@ -should-be-excluded.js -./build/a/should-be-excluded.js diff --git a/test/_fixtures/files-in-package-ignore/README b/test/_fixtures/files-in-package-ignore/README deleted file mode 100644 index e69de29..0000000 diff --git a/test/_fixtures/files-in-package-ignore/build/a/b/c/d.js b/test/_fixtures/files-in-package-ignore/build/a/b/c/d.js deleted file mode 100644 index e69de29..0000000 diff --git a/test/_fixtures/files-in-package-ignore/build/a/e.js b/test/_fixtures/files-in-package-ignore/build/a/e.js deleted file mode 100644 index e69de29..0000000 diff --git a/test/_fixtures/files-in-package-ignore/build/a/should-be-excluded.js b/test/_fixtures/files-in-package-ignore/build/a/should-be-excluded.js deleted file mode 100644 index e69de29..0000000 diff --git a/test/_fixtures/files-in-package-ignore/package.json b/test/_fixtures/files-in-package-ignore/package.json deleted file mode 100644 index cc6680e..0000000 --- a/test/_fixtures/files-in-package-ignore/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "files": [ - "build" - ] -} diff --git a/test/_fixtures/files-in-package-ignore/should-be-excluded.js b/test/_fixtures/files-in-package-ignore/should-be-excluded.js deleted file mode 100644 index e69de29..0000000 diff --git a/test/_fixtures/files-in-package/.DS_Store b/test/_fixtures/files-in-package/.DS_Store deleted file mode 100644 index e69de29..0000000 diff --git a/test/_fixtures/files-in-package/build/a/b/c/d.js b/test/_fixtures/files-in-package/build/a/b/c/d.js deleted file mode 100644 index e69de29..0000000 diff --git a/test/_fixtures/files-in-package/build/a/e.js b/test/_fixtures/files-in-package/build/a/e.js deleted file mode 100644 index e69de29..0000000 diff --git a/test/_fixtures/files-in-package/package.json b/test/_fixtures/files-in-package/package.json deleted file mode 100644 index cc6680e..0000000 --- a/test/_fixtures/files-in-package/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "files": [ - "build" - ] -} diff --git a/test/_fixtures/files-in-package/should-be-excluded.js b/test/_fixtures/files-in-package/should-be-excluded.js deleted file mode 100644 index e69de29..0000000 diff --git a/test/_fixtures/files-overrides-gitignore/.gitignore b/test/_fixtures/files-overrides-gitignore/.gitignore deleted file mode 100644 index db54e80..0000000 --- a/test/_fixtures/files-overrides-gitignore/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -ignore-me.js -test.json diff --git a/test/_fixtures/files-overrides-gitignore/ignore-me.js b/test/_fixtures/files-overrides-gitignore/ignore-me.js deleted file mode 100644 index 36fb240..0000000 --- a/test/_fixtures/files-overrides-gitignore/ignore-me.js +++ /dev/null @@ -1 +0,0 @@ -// this should be ignored diff --git a/test/_fixtures/files-overrides-gitignore/package.json b/test/_fixtures/files-overrides-gitignore/package.json deleted file mode 100644 index d7bb129..0000000 --- a/test/_fixtures/files-overrides-gitignore/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "files": [ - "test.js", - "test.json" - ] -} diff --git a/test/_fixtures/files-overrides-gitignore/test.js b/test/_fixtures/files-overrides-gitignore/test.js deleted file mode 100644 index d08f33f..0000000 --- a/test/_fixtures/files-overrides-gitignore/test.js +++ /dev/null @@ -1 +0,0 @@ -// include me diff --git a/test/_fixtures/files-overrides-gitignore/test.json b/test/_fixtures/files-overrides-gitignore/test.json deleted file mode 100644 index 4c82741..0000000 --- a/test/_fixtures/files-overrides-gitignore/test.json +++ /dev/null @@ -1 +0,0 @@ -{ "include": "me" } diff --git a/test/_fixtures/hashes/dei.png b/test/_fixtures/hashes/dei.png deleted file mode 100644 index 54279df..0000000 Binary files a/test/_fixtures/hashes/dei.png and /dev/null differ diff --git a/test/_fixtures/hashes/duplicate/dei.png b/test/_fixtures/hashes/duplicate/dei.png deleted file mode 100644 index 54279df..0000000 Binary files a/test/_fixtures/hashes/duplicate/dei.png and /dev/null differ diff --git a/test/_fixtures/hashes/index.js b/test/_fixtures/hashes/index.js deleted file mode 100644 index 96b3774..0000000 --- a/test/_fixtures/hashes/index.js +++ /dev/null @@ -1 +0,0 @@ -woot diff --git a/test/_fixtures/hashes/package.json b/test/_fixtures/hashes/package.json deleted file mode 100644 index 2f91cf5..0000000 --- a/test/_fixtures/hashes/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "hashes", - "version": "0.0.1", - "description": "", - "dependencies": {} -} diff --git a/test/_fixtures/multiple-manifests-throws/Dockerfile b/test/_fixtures/multiple-manifests-throws/Dockerfile deleted file mode 100644 index a86da2e..0000000 --- a/test/_fixtures/multiple-manifests-throws/Dockerfile +++ /dev/null @@ -1 +0,0 @@ -CMD echo 'world' diff --git a/test/_fixtures/multiple-manifests-throws/package.json b/test/_fixtures/multiple-manifests-throws/package.json deleted file mode 100644 index 6d41fe6..0000000 --- a/test/_fixtures/multiple-manifests-throws/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "simple" -} diff --git a/test/_fixtures/negation/a.js b/test/_fixtures/negation/a.js deleted file mode 100644 index 31dd7f2..0000000 --- a/test/_fixtures/negation/a.js +++ /dev/null @@ -1 +0,0 @@ -// should include it diff --git a/test/_fixtures/negation/package.json b/test/_fixtures/negation/package.json deleted file mode 100644 index 2a15744..0000000 --- a/test/_fixtures/negation/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "negation", - "version": "0.0.1", - "description": "", - "dependencies": { - - } -} diff --git a/test/_fixtures/nested-node_modules/.npmignore b/test/_fixtures/nested-node_modules/.npmignore deleted file mode 100644 index cf70988..0000000 --- a/test/_fixtures/nested-node_modules/.npmignore +++ /dev/null @@ -1 +0,0 @@ -**/node_modules diff --git a/test/_fixtures/nested-node_modules/index.js b/test/_fixtures/nested-node_modules/index.js deleted file mode 100644 index ce49d09..0000000 --- a/test/_fixtures/nested-node_modules/index.js +++ /dev/null @@ -1 +0,0 @@ -// this should be included diff --git a/test/_fixtures/nested-node_modules/package.json b/test/_fixtures/nested-node_modules/package.json deleted file mode 100644 index c8b63e1..0000000 --- a/test/_fixtures/nested-node_modules/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "nested-node_modules" -} diff --git a/test/_fixtures/no-node_modules/index.js b/test/_fixtures/no-node_modules/index.js deleted file mode 100644 index 33ddd72..0000000 --- a/test/_fixtures/no-node_modules/index.js +++ /dev/null @@ -1 +0,0 @@ -console.log('index'); diff --git a/test/_fixtures/no-node_modules/package.json b/test/_fixtures/no-node_modules/package.json deleted file mode 100644 index ba08cb9..0000000 --- a/test/_fixtures/no-node_modules/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "no-node_modules", - "version": "0.0.1", - "description": "", - "dependencies": {} -} diff --git a/test/_fixtures/now-files-overrides-npmignore/.npmignore b/test/_fixtures/now-files-overrides-npmignore/.npmignore deleted file mode 100644 index db54e80..0000000 --- a/test/_fixtures/now-files-overrides-npmignore/.npmignore +++ /dev/null @@ -1,2 +0,0 @@ -ignore-me.js -test.json diff --git a/test/_fixtures/now-files-overrides-npmignore/ignore-me.js b/test/_fixtures/now-files-overrides-npmignore/ignore-me.js deleted file mode 100644 index 36fb240..0000000 --- a/test/_fixtures/now-files-overrides-npmignore/ignore-me.js +++ /dev/null @@ -1 +0,0 @@ -// this should be ignored diff --git a/test/_fixtures/now-files-overrides-npmignore/package.json b/test/_fixtures/now-files-overrides-npmignore/package.json deleted file mode 100644 index 7dc492c..0000000 --- a/test/_fixtures/now-files-overrides-npmignore/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "now": { - "files": [ - "test.js", - "test.json" - ] - } -} diff --git a/test/_fixtures/now-files-overrides-npmignore/test.js b/test/_fixtures/now-files-overrides-npmignore/test.js deleted file mode 100644 index d08f33f..0000000 --- a/test/_fixtures/now-files-overrides-npmignore/test.js +++ /dev/null @@ -1 +0,0 @@ -// include me diff --git a/test/_fixtures/now-files-overrides-npmignore/test.json b/test/_fixtures/now-files-overrides-npmignore/test.json deleted file mode 100644 index 4c82741..0000000 --- a/test/_fixtures/now-files-overrides-npmignore/test.json +++ /dev/null @@ -1 +0,0 @@ -{ "include": "me" } diff --git a/test/_fixtures/now-files/a.js b/test/_fixtures/now-files/a.js deleted file mode 100644 index 95c1988..0000000 --- a/test/_fixtures/now-files/a.js +++ /dev/null @@ -1 +0,0 @@ -// should not be included diff --git a/test/_fixtures/now-files/b.js b/test/_fixtures/now-files/b.js deleted file mode 100644 index dcdb2da..0000000 --- a/test/_fixtures/now-files/b.js +++ /dev/null @@ -1 +0,0 @@ -// should be included diff --git a/test/_fixtures/now-files/package.json b/test/_fixtures/now-files/package.json deleted file mode 100644 index 8796369..0000000 --- a/test/_fixtures/now-files/package.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "name": "woot", - "version": "0.0.1", - "description": "", - "dependencies": {}, - "files": [ - "a.js" - ], - "now": { - "files": [ - "b.js" - ] - } -} diff --git a/test/_fixtures/now-json-docker/Dockerfile b/test/_fixtures/now-json-docker/Dockerfile deleted file mode 100644 index a86da2e..0000000 --- a/test/_fixtures/now-json-docker/Dockerfile +++ /dev/null @@ -1 +0,0 @@ -CMD echo 'world' diff --git a/test/_fixtures/now-json-docker/a.js b/test/_fixtures/now-json-docker/a.js deleted file mode 100644 index 95c1988..0000000 --- a/test/_fixtures/now-json-docker/a.js +++ /dev/null @@ -1 +0,0 @@ -// should not be included diff --git a/test/_fixtures/now-json-docker/b.js b/test/_fixtures/now-json-docker/b.js deleted file mode 100644 index dcdb2da..0000000 --- a/test/_fixtures/now-json-docker/b.js +++ /dev/null @@ -1 +0,0 @@ -// should be included diff --git a/test/_fixtures/now-json-docker/now.json b/test/_fixtures/now-json-docker/now.json deleted file mode 100644 index 5acf2cb..0000000 --- a/test/_fixtures/now-json-docker/now.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "files": [ - "b.js" - ] -} diff --git a/test/_fixtures/now-json-throws/now.json b/test/_fixtures/now-json-throws/now.json deleted file mode 100644 index 087ce94..0000000 --- a/test/_fixtures/now-json-throws/now.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "alias": "bar.com" -} diff --git a/test/_fixtures/now-json-throws/package.json b/test/_fixtures/now-json-throws/package.json deleted file mode 100644 index 350ad6c..0000000 --- a/test/_fixtures/now-json-throws/package.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "woot", - "version": "0.0.1", - "description": "", - "dependencies": {}, - "now": { - "alias": "foo.com" - } -} diff --git a/test/_fixtures/now-json/a.js b/test/_fixtures/now-json/a.js deleted file mode 100644 index 95c1988..0000000 --- a/test/_fixtures/now-json/a.js +++ /dev/null @@ -1 +0,0 @@ -// should not be included diff --git a/test/_fixtures/now-json/b.js b/test/_fixtures/now-json/b.js deleted file mode 100644 index dcdb2da..0000000 --- a/test/_fixtures/now-json/b.js +++ /dev/null @@ -1 +0,0 @@ -// should be included diff --git a/test/_fixtures/now-json/now.json b/test/_fixtures/now-json/now.json deleted file mode 100644 index 5acf2cb..0000000 --- a/test/_fixtures/now-json/now.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "files": [ - "b.js" - ] -} diff --git a/test/_fixtures/now-json/package.json b/test/_fixtures/now-json/package.json deleted file mode 100644 index c679e7f..0000000 --- a/test/_fixtures/now-json/package.json +++ /dev/null @@ -1,9 +0,0 @@ -{ - "name": "woot", - "version": "0.0.1", - "description": "", - "dependencies": {}, - "files": [ - "a.js" - ] -} diff --git a/test/_fixtures/prefix-regression/.npmignore b/test/_fixtures/prefix-regression/.npmignore deleted file mode 100644 index 96b3774..0000000 --- a/test/_fixtures/prefix-regression/.npmignore +++ /dev/null @@ -1 +0,0 @@ -woot diff --git a/test/_fixtures/prefix-regression/package.json b/test/_fixtures/prefix-regression/package.json deleted file mode 100644 index 196283f..0000000 --- a/test/_fixtures/prefix-regression/package.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "name": "prefix-regression", - "version": "0.0.1", - "description": "", - "dependencies": {} -} diff --git a/test/_fixtures/prefix-regression/woot.js b/test/_fixtures/prefix-regression/woot.js deleted file mode 100644 index 82ccf67..0000000 --- a/test/_fixtures/prefix-regression/woot.js +++ /dev/null @@ -1 +0,0 @@ -// hello diff --git a/test/_fixtures/simple-main/build/a.js b/test/_fixtures/simple-main/build/a.js deleted file mode 100644 index e69de29..0000000 diff --git a/test/_fixtures/simple-main/index.js b/test/_fixtures/simple-main/index.js deleted file mode 100644 index e69de29..0000000 diff --git a/test/_fixtures/simple-main/package.json b/test/_fixtures/simple-main/package.json deleted file mode 100644 index 3e56224..0000000 --- a/test/_fixtures/simple-main/package.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "name": "simple-with-main", - "version": "0.0.1", - "description": "", - "main": "./index.js", - "dependencies": {} -} diff --git a/test/_fixtures/simple/bin/test b/test/_fixtures/simple/bin/test deleted file mode 100644 index e69de29..0000000 diff --git a/test/_fixtures/simple/index.js b/test/_fixtures/simple/index.js deleted file mode 100644 index e69de29..0000000 diff --git a/test/_fixtures/simple/lib/woot b/test/_fixtures/simple/lib/woot deleted file mode 100644 index e69de29..0000000 diff --git a/test/_fixtures/simple/lib/woot.jsx b/test/_fixtures/simple/lib/woot.jsx deleted file mode 100644 index e69de29..0000000 diff --git a/test/_fixtures/simple/package.json b/test/_fixtures/simple/package.json deleted file mode 100644 index 6d41fe6..0000000 --- a/test/_fixtures/simple/package.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "name": "simple" -} diff --git a/test/_fixtures/type-in-package-now-with-dockerfile/Dockerfile b/test/_fixtures/type-in-package-now-with-dockerfile/Dockerfile deleted file mode 100644 index a86da2e..0000000 --- a/test/_fixtures/type-in-package-now-with-dockerfile/Dockerfile +++ /dev/null @@ -1 +0,0 @@ -CMD echo 'world' diff --git a/test/_fixtures/type-in-package-now-with-dockerfile/package.json b/test/_fixtures/type-in-package-now-with-dockerfile/package.json deleted file mode 100644 index a48ec2d..0000000 --- a/test/_fixtures/type-in-package-now-with-dockerfile/package.json +++ /dev/null @@ -1,5 +0,0 @@ -{ - "now": { - "type": "npm" - } -} diff --git a/test/args-parsing.js b/test/args-parsing.js deleted file mode 100644 index bc7a5d6..0000000 --- a/test/args-parsing.js +++ /dev/null @@ -1,93 +0,0 @@ -const path = require('path') -const test = require('ava') -const { spawn } = require('cross-spawn') - -const logo = require('../lib/utils/output/logo') - -const deployHelpMessage = `${logo} now [options] ` -const aliasHelpMessage = `${logo} now alias ` - -test('"now help" prints deploy help message', async t => { - const result = await now('help') - - t.is(result.code, 0) - const stdout = result.stdout.split('\n') - t.true(stdout.length > 1) - t.true(stdout[1].includes(deployHelpMessage)) -}) - -test('"now --help" prints deploy help message', async t => { - const result = await now('--help') - - t.is(result.code, 0) - const stdout = result.stdout.split('\n') - t.true(stdout.length > 1) - t.true(stdout[1].includes(deployHelpMessage)) -}) - -test('"now deploy --help" prints deploy help message', async t => { - const result = await now('deploy', '--help') - - t.is(result.code, 0) - const stdout = result.stdout.split('\n') - t.true(stdout.length > 1) - t.true(stdout[1].includes(deployHelpMessage)) -}) - -test('"now --help deploy" prints deploy help message', async t => { - const result = await now('--help', 'deploy') - - t.is(result.code, 0) - const stdout = result.stdout.split('\n') - t.true(stdout.length > 1) - t.true(stdout[1].includes(deployHelpMessage)) -}) - -test('"now help alias" prints alias help message', async t => { - const result = await now('help', 'alias') - - t.is(result.code, 0) - const stdout = result.stdout.split('\n') - t.true(stdout.length > 1) - t.true(stdout[1].includes(aliasHelpMessage)) -}) - -test('"now alias --help" is the same as "now --help alias"', async t => { - const [result1, result2] = await Promise.all([ - now('alias', '--help'), - now('--help', 'alias') - ]) - - t.is(result1.code, 0) - t.is(result1.code, result2.code) - t.is(result1.stdout, result2.stdout) -}) - -/** - * Run the built now binary with given arguments - * - * @param {String} args string arguements - * @return {Promise} promise that resolves to an object {code, stdout} - */ -function now(...args) { - return new Promise((resolve, reject) => { - const command = path.resolve(__dirname, '../bin/now.js') - const now = spawn(command, args) - - let stdout = '' - now.stdout.on('data', data => { - stdout += data - }) - - now.on('error', err => { - reject(err) - }) - - now.on('close', code => { - resolve({ - code, - stdout - }) - }) - }) -} diff --git a/test/index.js b/test/index.js deleted file mode 100644 index 92bf9ee..0000000 --- a/test/index.js +++ /dev/null @@ -1,240 +0,0 @@ -// Native -const { join, resolve } = require('path') - -// Packages -const test = require('ava') -const { asc: alpha } = require('alpha-sort') - -// Ours -const hash = require('../lib/hash') -const readMetadata = require('../lib/read-metadata') -const { - npm: getNpmFiles_, - docker: getDockerFiles -} = require('../lib/get-files') - -const prefix = join(__dirname, '_fixtures') + '/' -const base = path => path.replace(prefix, '') -const fixture = name => resolve(`./test/_fixtures/${name}`) - -// Overload to force debugging -const getNpmFiles = async dir => { - const { pkg, nowConfig, hasNowJson } = await readMetadata(dir, { - quiet: true, - strict: false - }) - return getNpmFiles_(dir, pkg, nowConfig, { hasNowJson }) -} - -test('`files`', async t => { - let files = await getNpmFiles(fixture('files-in-package')) - t.is(files.length, 3) - files = files.sort(alpha) - t.is(base(files[0]), 'files-in-package/build/a/b/c/d.js') - t.is(base(files[1]), 'files-in-package/build/a/e.js') - t.is(base(files[2]), 'files-in-package/package.json') -}) - -test('`files` + `.*.swp` + `.npmignore`', async t => { - let files = await getNpmFiles(fixture('files-in-package-ignore')) - files = files.sort(alpha) - t.is(files.length, 3) - t.is(base(files[0]), 'files-in-package-ignore/build/a/b/c/d.js') - t.is(base(files[1]), 'files-in-package-ignore/build/a/e.js') - t.is(base(files[2]), 'files-in-package-ignore/package.json') -}) - -test('`files` overrides `.gitignore`', async t => { - let files = await getNpmFiles(fixture('files-overrides-gitignore')) - files = files.sort(alpha) - t.is(files.length, 3) - t.is(base(files[0]), 'files-overrides-gitignore/package.json') - t.is(base(files[1]), 'files-overrides-gitignore/test.js') - t.is(base(files[2]), 'files-overrides-gitignore/test.json') -}) - -test('`now.files` overrides `.npmignore`', async t => { - let files = await getNpmFiles(fixture('now-files-overrides-npmignore')) - files = files.sort(alpha) - t.is(files.length, 3) - t.is(base(files[0]), 'now-files-overrides-npmignore/package.json') - t.is(base(files[1]), 'now-files-overrides-npmignore/test.js') - t.is(base(files[2]), 'now-files-overrides-npmignore/test.json') -}) - -test('simple', async t => { - let files = await getNpmFiles(fixture('simple')) - files = files.sort(alpha) - t.is(files.length, 5) - t.is(base(files[0]), 'simple/bin/test') - t.is(base(files[1]), 'simple/index.js') - t.is(base(files[2]), 'simple/lib/woot') - t.is(base(files[3]), 'simple/lib/woot.jsx') - t.is(base(files[4]), 'simple/package.json') -}) - -test('simple with main', async t => { - let files = await getNpmFiles(fixture('simple-main')) - t.is(files.length, 3) - files = files.sort(alpha) - t.is(files.length, 3) - t.is(base(files[0]), 'simple-main/build/a.js') - t.is(base(files[1]), 'simple-main/index.js') - t.is(base(files[2]), 'simple-main/package.json') -}) - -test('directory main', async t => { - let files = await getNpmFiles(fixture('directory-main')) - t.is(files.length, 3) - files = files.sort(alpha) - t.is(files.length, 3) - t.is(base(files[0]), 'directory-main/a/index.js') - t.is(base(files[1]), 'directory-main/build/a.js') - t.is(base(files[2]), 'directory-main/package.json') -}) - -test('extensionless main', async t => { - let files = await getNpmFiles(fixture('extensionless-main')) - t.is(files.length, 3) - files = files.sort(alpha) - t.is(files.length, 3) - t.is(base(files[0]), 'extensionless-main/build/a.js') - t.is(base(files[1]), 'extensionless-main/index.js') - t.is(base(files[2]), 'extensionless-main/package.json') -}) - -test('hashes', async t => { - const files = await getNpmFiles(fixture('hashes')) - const hashes = await hash(files) - t.is(hashes.size, 3) - const many = new Set( - hashes.get('277c55a2042910b9fe706ad00859e008c1b7d172').names - ) - t.is(many.size, 2) - t.is(many.has(prefix + 'hashes/dei.png'), true) - t.is(many.has(prefix + 'hashes/duplicate/dei.png'), true) - t.is( - hashes.get('56c00d0466fc6bdd41b13dac5fc920cc30a63b45').names[0], - prefix + 'hashes/index.js' - ) - t.is( - hashes.get('706214f42ae940a01d2aa60c5e32408f4d2127dd').names[0], - prefix + 'hashes/package.json' - ) -}) - -test('ignore node_modules', async t => { - let files = await getNpmFiles(fixture('no-node_modules')) - files = files.sort(alpha) - t.is(files.length, 2) - t.is(base(files[0]), 'no-node_modules/index.js') - t.is(base(files[1]), 'no-node_modules/package.json') -}) - -test('ignore nested `node_modules` with .npmignore **', async t => { - let files = await getNpmFiles(fixture('nested-node_modules')) - files = files.sort(alpha) - t.is(files.length, 2) - t.is(base(files[0]), 'nested-node_modules/index.js') - t.is(base(files[1]), 'nested-node_modules/package.json') -}) - -test('support whitelisting with .npmignore and !', async t => { - let files = await getNpmFiles(fixture('negation')) - files = files.sort(alpha) - t.is(files.length, 2) - t.is(base(files[0]), 'negation/a.js') - t.is(base(files[1]), 'negation/package.json') -}) - -test('support `now.files`', async t => { - let files = await getNpmFiles(fixture('now-files')) - files = files.sort(alpha) - t.is(files.length, 2) - t.is(base(files[0]), 'now-files/b.js') - t.is(base(files[1]), 'now-files/package.json') -}) - -test('support docker', async t => { - let files = await getDockerFiles(fixture('dockerfile')) - files = files.sort(alpha) - t.is(files.length, 2) - t.is(base(files[0]), 'dockerfile/Dockerfile') - t.is(base(files[1]), 'dockerfile/a.js') -}) - -test('prefix regression', async t => { - let files = await getNpmFiles(fixture('prefix-regression')) - files = files.sort(alpha) - t.is(files.length, 2) - t.is(base(files[0]), 'prefix-regression/package.json') - t.is(base(files[1]), 'prefix-regression/woot.js') -}) - -test('support `now.json` files with package.json', async t => { - let files = await getNpmFiles(fixture('now-json')) - files = files.sort(alpha) - t.is(files.length, 3) - t.is(base(files[0]), 'now-json/b.js') - t.is(base(files[1]), 'now-json/now.json') - t.is(base(files[2]), 'now-json/package.json') -}) - -test('support `now.json` files with Dockerfile', async t => { - const f = fixture('now-json-docker') - const { deploymentType, nowConfig, hasNowJson } = await readMetadata(f, { - quiet: true, - strict: false - }) - t.is(deploymentType, 'docker') - - let files = await getDockerFiles(f, nowConfig, { hasNowJson }) - files = files.sort(alpha) - t.is(files.length, 3) - t.is(base(files[0]), 'now-json-docker/Dockerfile') - t.is(base(files[1]), 'now-json-docker/b.js') - t.is(base(files[2]), 'now-json-docker/now.json') -}) - -test('throws when both `now.json` and `package.json:now` exist', async t => { - let e - try { - await readMetadata(fixture('now-json-throws'), { - quiet: true, - strict: false - }) - } catch (err) { - e = err - } - t.is(e.name, 'Error') - t.is(e.userError, true) - t.pass( - /please ensure there's a single source of configuration/i.test(e.message) - ) -}) - -test('throws when `package.json` and `Dockerfile` exist', async t => { - let e - try { - await readMetadata(fixture('multiple-manifests-throws'), { - quiet: true, - strict: false - }) - } catch (err) { - e = err - } - t.is(e.userError, true) - t.is(e.code, 'MULTIPLE_MANIFESTS') - t.pass(/ambiguous deployment/i.test(e.message)) -}) - -test('support `package.json:now.type` to bypass multiple manifests error', async t => { - const f = fixture('type-in-package-now-with-dockerfile') - const { type, nowConfig, hasNowJson } = await readMetadata(f, { - quiet: true, - strict: false - }) - t.is(type, 'npm') - t.is(nowConfig.type, 'npm') - t.is(hasNowJson, false) -}) diff --git a/test/pack-now.js b/test/pack-now.js deleted file mode 100644 index 7fb6133..0000000 --- a/test/pack-now.js +++ /dev/null @@ -1,58 +0,0 @@ -const path = require('path') -const crossSpawn = require('cross-spawn') -const test = require('ava') - -const logo = require('../lib/utils/output/logo') - -test.serial('make binary', async t => { - if (!process.env.CI) { - t.true(true) - return - } - const result = await spawn('npm', ['run', 'pack']) - t.is(result.code, 0) -}) - -const binary = { - darwin: 'now-macos', - linux: 'now-linux', - win32: 'now-win.exe' -}[process.platform] - -const binaryPath = path.resolve(__dirname, '../packed/' + binary) -const deployHelpMessage = `${logo} now [options] ` - -test.serial('packed "now help" prints deploy help message', async t => { - if (!process.env.CI) { - t.true(true) - return - } - const result = await spawn(binaryPath, ['help']) - - t.is(result.code, 0) - const stdout = result.stdout.split('\n') - t.true(stdout.length > 1) - t.true(stdout[1].includes(deployHelpMessage)) -}) - -function spawn(command, args) { - return new Promise((resolve, reject) => { - const child = crossSpawn.spawn(command, args) - - let stdout = '' - child.stdout.on('data', data => { - stdout += data - }) - - child.on('error', err => { - reject(err) - }) - - child.on('close', code => { - resolve({ - code, - stdout - }) - }) - }) -} diff --git a/test/to-host.js b/test/to-host.js deleted file mode 100644 index 2d34666..0000000 --- a/test/to-host.js +++ /dev/null @@ -1,35 +0,0 @@ -const test = require('ava') -const toHost = require('../lib/to-host') - -test('simple', t => { - t.is(toHost('zeit.co'), 'zeit.co') -}) - -test('leading //', t => { - t.is(toHost('//zeit-logos-rnemgaicnc.now.sh'), 'zeit-logos-rnemgaicnc.now.sh') -}) - -test('leading http://', t => { - t.is( - toHost('http://zeit-logos-rnemgaicnc.now.sh'), - 'zeit-logos-rnemgaicnc.now.sh' - ) -}) - -test('leading https://', t => { - t.is( - toHost('https://zeit-logos-rnemgaicnc.now.sh'), - 'zeit-logos-rnemgaicnc.now.sh' - ) -}) - -test('leading https:// and path', t => { - t.is( - toHost('https://zeit-logos-rnemgaicnc.now.sh/path'), - 'zeit-logos-rnemgaicnc.now.sh' - ) -}) - -test('simple and path', t => { - t.is(toHost('zeit.co/test'), 'zeit.co') -})