Browse Source

Moved back to XO for linting

cc @sindresorhus
master
Leo Lamprecht 8 years ago
parent
commit
1f85f6d5db
  1. 12
      bin/now-alias.js
  2. 5
      bin/now-billing-add.js
  3. 4
      bin/now-billing.js
  4. 4
      bin/now-certs.js
  5. 22
      bin/now-deploy.js
  6. 4
      bin/now-dns.js
  7. 6
      bin/now-domains.js
  8. 2
      bin/now-list.js
  9. 2
      bin/now-open.js
  10. 4
      bin/now-remove.js
  11. 4
      bin/now-secrets.js
  12. 4
      bin/now-upgrade.js
  13. 4
      lib/agent.js
  14. 37
      lib/alias.js
  15. 8
      lib/build-logger.js
  16. 8
      lib/credit-cards.js
  17. 15
      lib/domain-records.js
  18. 3
      lib/domains.js
  19. 143
      lib/get-files.js
  20. 100
      lib/git.js
  21. 2
      lib/ignored.js
  22. 41
      lib/index.js
  23. 2
      lib/login.js
  24. 2
      lib/logs.js
  25. 2
      lib/pkg.js
  26. 7
      lib/plans.js
  27. 8
      lib/re-alias.js
  28. 8
      lib/read-metadata.js
  29. 2
      lib/strlen.js
  30. 2
      lib/to-host.js
  31. 2
      lib/utils/exit.js
  32. 4
      lib/utils/input/list.js
  33. 2
      lib/utils/input/prompt-bool.js
  34. 20
      lib/utils/input/text.js
  35. 2
      lib/utils/output/cmd.js
  36. 2
      lib/utils/output/code.js
  37. 2
      lib/utils/output/error.js
  38. 2
      lib/utils/output/info.js
  39. 2
      lib/utils/output/param.js
  40. 2
      lib/utils/output/stamp.js
  41. 2
      lib/utils/output/success.js
  42. 2
      lib/utils/output/uid.js
  43. 2
      lib/utils/output/wait.js
  44. 2
      lib/utils/to-human-path.js
  45. 29
      package.json
  46. 1
      readme.md
  47. 2
      test/index.js
  48. 12
      test/to-host.js

12
bin/now-alias.js

@ -32,7 +32,7 @@ const argv = minimist(process.argv.slice(2), {
const subcommand = argv._[0]; const subcommand = argv._[0];
// options // Options
const help = () => { const help = () => {
console.log( console.log(
` `
@ -92,7 +92,7 @@ const help = () => {
); );
}; };
// options // Options
const debug = argv.debug; const debug = argv.debug;
const apiUrl = argv.url || 'https://api.zeit.co'; const apiUrl = argv.url || 'https://api.zeit.co';
@ -211,7 +211,7 @@ async function run(token) {
); );
return [ return [
'', '',
// we default to `''` because some early aliases didn't // We default to `''` because some early aliases didn't
// have an uid associated // have an uid associated
_alias.uid === null ? '' : _alias.uid, _alias.uid === null ? '' : _alias.uid,
_sourceUrl, _sourceUrl,
@ -342,7 +342,9 @@ async function confirmDeploymentRemoval(alias, _alias) {
const msg = '> The following alias will be removed permanently\n' + const msg = '> The following alias will be removed permanently\n' +
` ${tbl} \nAre you sure?`; ` ${tbl} \nAre you sure?`;
return await promptBool(msg);
const prompted = await promptBool(msg);
return prompted;
} }
function findAlias(alias, list) { function findAlias(alias, list) {
@ -366,7 +368,7 @@ function findAlias(alias, list) {
return true; return true;
} }
// match prefix // Match prefix
if (`${val}.now.sh` === d.alias) { if (`${val}.now.sh` === d.alias) {
if (debug) { if (debug) {
console.log(`> [debug] matched alias ${d.uid} by url ${d.host}`); console.log(`> [debug] matched alias ${d.uid} by url ${d.host}`);

5
bin/now-billing-add.js

@ -117,6 +117,7 @@ module.exports = function(creditCards) {
} else if (typeof piece === 'object') { } else if (typeof piece === 'object') {
let result; let result;
try { try {
/* eslint-disable no-await-in-loop */
result = await textInput({ result = await textInput({
label: '- ' + piece.label, label: '- ' + piece.label,
initialValue: piece.initialValue || piece.value, initialValue: piece.initialValue || piece.value,
@ -126,7 +127,9 @@ module.exports = function(creditCards) {
validateValue: piece.validateValue, validateValue: piece.validateValue,
autoComplete: piece.autoComplete autoComplete: piece.autoComplete
}); });
piece.value = result; piece.value = result;
if (key === 'cardNumber') { if (key === 'cardNumber') {
let brand = cardBrands[ccValidator.determineCardType(result)]; let brand = cardBrands[ccValidator.determineCardType(result)];
piece.brand = brand; piece.brand = brand;
@ -178,7 +181,7 @@ module.exports = function(creditCards) {
} }
} }
} }
console.log(''); // new line console.log(''); // New line
const stopSpinner = wait('Saving card'); const stopSpinner = wait('Saving card');
try { try {

4
bin/now-billing.js

@ -69,7 +69,7 @@ const help = () => {
); );
}; };
// options // Options
const debug = argv.debug; const debug = argv.debug;
const apiUrl = argv.url || 'https://api.zeit.co'; const apiUrl = argv.url || 'https://api.zeit.co';
@ -78,7 +78,7 @@ if (argv.config) {
} }
const exit = code => { const exit = code => {
// we give stdout some time to flush out // We give stdout some time to flush out
// because there's a node bug where // because there's a node bug where
// stdout writes are asynchronous // stdout writes are asynchronous
// https://github.com/nodejs/node/issues/6456 // https://github.com/nodejs/node/issues/6456

4
bin/now-certs.js

@ -32,7 +32,7 @@ const argv = minimist(process.argv.slice(2), {
const subcommand = argv._[0]; const subcommand = argv._[0];
// options // Options
const help = () => { const help = () => {
console.log( console.log(
` `
@ -73,7 +73,7 @@ const help = () => {
); );
}; };
// options // Options
const debug = argv.debug; const debug = argv.debug;
const apiUrl = argv.url || 'https://api.zeit.co'; const apiUrl = argv.url || 'https://api.zeit.co';

22
bin/now-deploy.js

@ -146,7 +146,7 @@ const help = () => {
let path = argv._[0]; let path = argv._[0];
if (path) { if (path) {
// if path is relative: resolve // If path is relative: resolve
// if path is absolute: clear up strange `/` etc // if path is absolute: clear up strange `/` etc
path = resolve(process.cwd(), path); path = resolve(process.cwd(), path);
} else { } else {
@ -156,7 +156,7 @@ if (path) {
// If the current deployment is a repo // If the current deployment is a repo
const gitRepo = {}; const gitRepo = {};
// options // Options
let forceNew = argv.force; let forceNew = argv.force;
const debug = argv.debug; const debug = argv.debug;
const clipboard = !argv['no-clipboard']; const clipboard = !argv['no-clipboard'];
@ -483,7 +483,7 @@ async function sync(token) {
console.log( console.log(
`> Reading ${chalk.bold(`"${chalk.bold(key)}"`)} from your env (as no value was specified)` `> Reading ${chalk.bold(`"${chalk.bold(key)}"`)} from your env (as no value was specified)`
); );
// escape value if it begins with @ // Escape value if it begins with @
val = process.env[key].replace(/^@/, '\\@'); val = process.env[key].replace(/^@/, '\\@');
} else { } else {
error( error(
@ -585,10 +585,10 @@ async function sync(token) {
console.log('> Initializing…'); console.log('> Initializing…');
} }
// close http2 agent // Close http2 agent
now.close(); now.close();
// show build logs // Show build logs
printLogs(now.host, token); printLogs(now.host, token);
}; };
@ -624,16 +624,16 @@ async function sync(token) {
console.log(`> Initializing…`); console.log(`> Initializing…`);
} }
// close http2 agent // Close http2 agent
now.close(); now.close();
// show build logs // Show build logs
printLogs(now.host, token); printLogs(now.host, token);
} }
} }
function printLogs(host, token) { function printLogs(host, token) {
// log build // Log build
const logger = new Logger(host, { debug, quiet }); const logger = new Logger(host, { debug, quiet });
logger.on('error', async err => { logger.on('error', async err => {
@ -663,9 +663,13 @@ function printLogs(host, token) {
const aliasList = autoAliases.filter(item => item !== ''); const aliasList = autoAliases.filter(item => item !== '');
if (aliasList.length > 0) { if (aliasList.length > 0) {
const assignments = [];
for (const alias of aliasList) { for (const alias of aliasList) {
await assignAlias(alias, token, host, apiUrl, debug); assignments.push(assignAlias(alias, token, host, apiUrl, debug));
} }
await Promise.all(assignments);
} else { } else {
await reAlias(token, host, help, exit, apiUrl, debug); await reAlias(token, host, help, exit, apiUrl, debug);
} }

4
bin/now-dns.js

@ -29,7 +29,7 @@ const argv = minimist(process.argv.slice(2), {
const subcommand = argv._[0]; const subcommand = argv._[0];
// options // Options
const help = () => { const help = () => {
console.log( console.log(
` `
@ -65,7 +65,7 @@ const help = () => {
); );
}; };
// options // Options
const debug = argv.debug; const debug = argv.debug;
const apiUrl = argv.url || 'https://api.zeit.co'; const apiUrl = argv.url || 'https://api.zeit.co';
if (argv.config) { if (argv.config) {

6
bin/now-domains.js

@ -31,7 +31,7 @@ const argv = minimist(process.argv.slice(2), {
const subcommand = argv._[0]; const subcommand = argv._[0];
// options // Options
const help = () => { const help = () => {
console.log( console.log(
` `
@ -99,7 +99,7 @@ const help = () => {
); );
}; };
// options // Options
const debug = argv.debug; const debug = argv.debug;
const apiUrl = argv.url || 'https://api.zeit.co'; const apiUrl = argv.url || 'https://api.zeit.co';
@ -319,7 +319,7 @@ function findDomain(val, list) {
return true; return true;
} }
// match prefix // Match prefix
if (d.name === toHost(val)) { if (d.name === toHost(val)) {
if (debug) { if (debug) {
console.log(`> [debug] matched domain ${d.uid} by name ${d.name}`); console.log(`> [debug] matched domain ${d.uid} by name ${d.name}`);

2
bin/now-list.js

@ -61,7 +61,7 @@ if (argv.help) {
const app = argv._[0]; const app = argv._[0];
// options // Options
const debug = argv.debug; const debug = argv.debug;
const apiUrl = argv.url || 'https://api.zeit.co'; const apiUrl = argv.url || 'https://api.zeit.co';

2
bin/now-open.js

@ -53,7 +53,7 @@ if (argv.help) {
const app = argv._[0]; const app = argv._[0];
// options // Options
const debug = argv.debug; const debug = argv.debug;
const apiUrl = argv.url || 'https://api.zeit.co'; const apiUrl = argv.url || 'https://api.zeit.co';

4
bin/now-remove.js

@ -28,7 +28,7 @@ const argv = minimist(process.argv.slice(2), {
const ids = argv._; const ids = argv._;
// options // Options
const help = () => { const help = () => {
console.log( console.log(
` `
@ -66,7 +66,7 @@ if (argv.help || ids.length === 0) {
process.exit(0); process.exit(0);
} }
// options // Options
const debug = argv.debug; const debug = argv.debug;
const apiUrl = argv.url || 'https://api.zeit.co'; const apiUrl = argv.url || 'https://api.zeit.co';
const hard = argv.hard || false; const hard = argv.hard || false;

4
bin/now-secrets.js

@ -29,7 +29,7 @@ const argv = minimist(process.argv.slice(2), {
const subcommand = argv._[0]; const subcommand = argv._[0];
// options // Options
const help = () => { const help = () => {
console.log( console.log(
` `
@ -74,7 +74,7 @@ const help = () => {
); );
}; };
// options // Options
const debug = argv.debug; const debug = argv.debug;
const apiUrl = argv.url || 'https://api.zeit.co'; const apiUrl = argv.url || 'https://api.zeit.co';

4
bin/now-upgrade.js

@ -58,7 +58,7 @@ const help = () => {
); );
}; };
// options // Options
const debug = argv.debug; const debug = argv.debug;
const apiUrl = argv.url || 'https://api.zeit.co'; const apiUrl = argv.url || 'https://api.zeit.co';
@ -67,7 +67,7 @@ if (argv.config) {
} }
const exit = code => { const exit = code => {
// we give stdout some time to flush out // We give stdout some time to flush out
// because there's a node bug where // because there's a node bug where
// stdout writes are asynchronous // stdout writes are asynchronous
// https://github.com/nodejs/node/issues/6456 // https://github.com/nodejs/node/issues/6456

4
lib/agent.js

@ -30,11 +30,11 @@ module.exports = class Agent {
_initAgent() { _initAgent() {
const module = this._protocol === 'https:' ? https : http; const module = this._protocol === 'https:' ? https : http;
const agent = (this._agent = new module.Agent({ this._agent = new module.Agent({
keepAlive: true, keepAlive: true,
keepAliveMsecs: 10000, keepAliveMsecs: 10000,
maxSockets: 8 maxSockets: 8
}).on('error', err => this._onError(err, agent))); }).on('error', err => this._onError(err, this._agent));
} }
_onError(err, agent) { _onError(err, agent) {

37
lib/alias.js

@ -82,7 +82,7 @@ module.exports = class Alias extends Now {
return true; return true;
} }
// match prefix // Match prefix
if (`${val}.now.sh` === d.url) { if (`${val}.now.sh` === d.url) {
if (this._debug) { if (this._debug) {
console.log(`> [debug] matched deployment ${d.uid} by url ${d.url}`); console.log(`> [debug] matched deployment ${d.uid} by url ${d.url}`);
@ -99,8 +99,9 @@ module.exports = class Alias extends Now {
async updatePathBasedroutes(alias, rules) { async updatePathBasedroutes(alias, rules) {
alias = await this.maybeSetUpDomain(alias); alias = await this.maybeSetUpDomain(alias);
const upsert = await this.upsertPathAlias(alias, rules);
return await this.upsertPathAlias(alias, rules); return upsert;
} }
async upsertPathAlias(alias, rules) { async upsertPathAlias(alias, rules) {
@ -130,7 +131,7 @@ module.exports = class Alias extends Now {
return body; return body;
} }
// no retry on authorization problems // No retry on authorization problems
if (res.status === 403) { if (res.status === 403) {
const code = body.error.code; const code = body.error.code;
@ -161,7 +162,7 @@ module.exports = class Alias extends Now {
return bail(new Error('Authorization error')); return bail(new Error('Authorization error'));
} }
// all other errors // All other errors
if (body.error) { if (body.error) {
const code = body.error.code; const code = body.error.code;
@ -173,13 +174,13 @@ module.exports = class Alias extends Now {
try { try {
await this.createCert(alias); await this.createCert(alias);
} catch (err) { } catch (err) {
// we bail to avoid retrying the whole process // We bail to avoid retrying the whole process
// of aliasing which would involve too many // of aliasing which would involve too many
// retries on certificate provisioning // retries on certificate provisioning
return bail(err); return bail(err);
} }
// try again, but now having provisioned the certificate // Try again, but now having provisioned the certificate
return this.upsertPathAlias(alias, rules); return this.upsertPathAlias(alias, rules);
} }
@ -199,7 +200,7 @@ module.exports = class Alias extends Now {
return bail(new Error(body.error.message)); return bail(new Error(body.error.message));
} }
// the two expected succesful cods are 200 and 304 // The two expected succesful cods are 200 and 304
if (res.status !== 200 && res.status !== 304) { if (res.status !== 200 && res.status !== 304) {
throw new Error('Unhandled error'); throw new Error('Unhandled error');
} }
@ -307,7 +308,7 @@ module.exports = class Alias extends Now {
return { uid: body.error.uid }; return { uid: body.error.uid };
} }
// no retry on authorization problems // No retry on authorization problems
if (res.status === 403) { if (res.status === 403) {
const code = body.error.code; const code = body.error.code;
@ -338,7 +339,7 @@ module.exports = class Alias extends Now {
return bail(new Error('Authorization error')); return bail(new Error('Authorization error'));
} }
// all other errors // All other errors
if (body.error) { if (body.error) {
const code = body.error.code; const code = body.error.code;
@ -354,13 +355,13 @@ module.exports = class Alias extends Now {
try { try {
await this.createCert(alias); await this.createCert(alias);
} catch (err) { } catch (err) {
// we bail to avoid retrying the whole process // We bail to avoid retrying the whole process
// of aliasing which would involve too many // of aliasing which would involve too many
// retries on certificate provisioning // retries on certificate provisioning
return bail(err); return bail(err);
} }
// try again, but now having provisioned the certificate // Try again, but now having provisioned the certificate
return this.createAlias(depl, alias); return this.createAlias(depl, alias);
} }
@ -379,7 +380,7 @@ module.exports = class Alias extends Now {
return bail(new Error(body.error.message)); return bail(new Error(body.error.message));
} }
// the two expected succesful cods are 200 and 304 // The two expected succesful cods are 200 and 304
if (res.status !== 200 && res.status !== 304) { if (res.status !== 200 && res.status !== 304) {
throw new Error('Unhandled error'); throw new Error('Unhandled error');
} }
@ -429,13 +430,13 @@ module.exports = class Alias extends Now {
} }
async maybeSetUpDomain(alias) { async maybeSetUpDomain(alias) {
// make alias lowercase // Make alias lowercase
alias = alias.toLowerCase(); alias = alias.toLowerCase();
// trim leading and trailing dots // Trim leading and trailing dots
// for example: `google.com.` => `google.com` // for example: `google.com.` => `google.com`
alias = alias.replace(/^\.+/, '').replace(/\.+$/, ''); alias = alias.replace(/^\.+/, '').replace(/\.+$/, '');
// evaluate the alias // Evaluate the alias
if (/\./.test(alias)) { if (/\./.test(alias)) {
alias = toHost(alias); alias = toHost(alias);
} else { } else {
@ -511,7 +512,7 @@ module.exports = class Alias extends Now {
} }
} catch (err) { } catch (err) {
if (err.userError) { if (err.userError) {
// a user error would imply that verification failed // A user error would imply that verification failed
// in which case we attempt to correct the dns // in which case we attempt to correct the dns
// configuration (if we can!) // configuration (if we can!)
try { try {
@ -521,7 +522,7 @@ module.exports = class Alias extends Now {
); );
const record = alias.substr(0, alias.length - domain.length); const record = alias.substr(0, alias.length - domain.length);
// lean up trailing and leading dots // Lean up trailing and leading dots
const _record = record.replace(/^\./, '').replace(/\.$/, ''); const _record = record.replace(/^\./, '').replace(/\.$/, '');
const _domain = domain.replace(/^\./, '').replace(/\.$/, ''); const _domain = domain.replace(/^\./, '').replace(/\.$/, '');
@ -615,7 +616,7 @@ module.exports = class Alias extends Now {
err.code === 'ESERVFAIL' || err.code === 'ESERVFAIL' ||
err.code === 'ENOTFOUND' err.code === 'ENOTFOUND'
) { ) {
// not errors per se, just absence of records // Not errors per se, just absence of records
if (this._debug) { if (this._debug) {
console.log(`> [debug] No records found for "${domain}"`); console.log(`> [debug] No records found for "${domain}"`);
} }

8
lib/build-logger.js

@ -39,7 +39,7 @@ module.exports = class Logger extends EventEmitter {
this.debug = debug; this.debug = debug;
this.quiet = quiet; this.quiet = quiet;
// readyState // ReadyState
this.building = false; this.building = false;
this.socket = io(`https://io.now.sh/states?host=${host}&v=2`); this.socket = io(`https://io.now.sh/states?host=${host}&v=2`);
@ -50,12 +50,12 @@ module.exports = class Logger extends EventEmitter {
this.lines = new Lines(10); this.lines = new Lines(10);
// log buffer // Log buffer
this.buf = []; this.buf = [];
} }
onState(state) { onState(state) {
// console.log(state) // Console.log(state)
if (!state.id) { if (!state.id) {
console.error('> Deployment not found'); console.error('> Deployment not found');
this.emit('error'); this.emit('error');
@ -116,7 +116,7 @@ module.exports = class Logger extends EventEmitter {
this.buf.sort((a, b) => compare(a.log, b.log)); this.buf.sort((a, b) => compare(a.log, b.log));
// flush all buffer // Flush all buffer
for (const b of this.buf) { for (const b of this.buf) {
clearTimeout(b.timer); clearTimeout(b.timer);
this.printLog(b.log); this.printLog(b.log);

8
lib/credit-cards.js

@ -57,14 +57,12 @@ module.exports = class CreditCards extends Now {
last4: body.card.last4 last4: body.card.last4
}); });
} else if (body.error && body.error.message) { } else if (body.error && body.error.message) {
reject({ message: body.error.message }); reject(new Error(body.error.message));
} else { } else {
reject('Unknown error'); reject(new Error('Unknown error'));
} }
} catch (err) { } catch (err) {
reject({ reject(new Error(err.message || 'Unknown error'));
message: err.message || 'Unknown error'
});
} }
}); });
} }

15
lib/domain-records.js

@ -29,8 +29,11 @@ module.exports = class DomainRecords extends Now {
} }
const records = new Map(); const records = new Map();
const bodies = [];
for (const domain of domains) { for (const domain of domains) {
const body = await this.retry(async (bail, attempt) => { bodies.push(
this.retry(async (bail, attempt) => {
const url = `/domains/${domain}/records`; const url = `/domains/${domain}/records`;
if (this._debug) { if (this._debug) {
console.time(`> [debug] #${attempt} GET ${url}`); console.time(`> [debug] #${attempt} GET ${url}`);
@ -48,9 +51,15 @@ module.exports = class DomainRecords extends Now {
} }
return body; return body;
}); })
);
}
const domainList = await Promise.all(bodies);
for (const body of domainList) {
records.set( records.set(
domain, body,
body.records.sort((a, b) => a.slug.localeCompare(b.slug)) body.records.sort((a, b) => a.slug.localeCompare(b.slug))
); );
} }

3
lib/domains.js

@ -10,7 +10,8 @@ const domainRegex = /^((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-
module.exports = class Domains extends Now { module.exports = class Domains extends Now {
async ls() { async ls() {
return await this.listDomains(); const domains = await this.listDomains();
return domains;
} }
async rm(name) { async rm(name) {

143
lib/get-files.js

@ -11,6 +11,57 @@ const { stat, readdir, readFile } = require('fs-promise');
// Ours // Ours
const IGNORED = require('./ignored'); 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 * Returns a list of files in the given
* directory that are subject to be * directory that are subject to be
@ -36,10 +87,10 @@ async function npm(
) { ) {
const whitelist = (nowConfig && nowConfig.files) || pkg.files; const whitelist = (nowConfig && nowConfig.files) || pkg.files;
// the package.json `files` whitelist still // The package.json `files` whitelist still
// honors ignores: https://docs.npmjs.com/files/package.json#files // honors ignores: https://docs.npmjs.com/files/package.json#files
const search_ = whitelist || ['.']; const search_ = whitelist || ['.'];
// convert all filenames into absolute paths // Convert all filenames into absolute paths
const search = Array.prototype.concat.apply( const search = Array.prototype.concat.apply(
[], [],
await Promise.all( await Promise.all(
@ -47,12 +98,12 @@ async function npm(
) )
); );
// always include the "main" file // Always include the "main" file
if (pkg.main) { if (pkg.main) {
search.push(require.resolve(resolve(path, pkg.main), 'may-exclude')); // pkg: may-exclude suppresses warnings search.push(require.resolve(resolve(path, pkg.main), 'may-exclude')); // Pkg: may-exclude suppresses warnings
} }
// compile list of ignored patterns and files // Compile list of ignored patterns and files
const npmIgnore = await maybeRead(resolve(path, '.npmignore'), null); const npmIgnore = await maybeRead(resolve(path, '.npmignore'), null);
const gitIgnore = npmIgnore === null const gitIgnore = npmIgnore === null
? await maybeRead(resolve(path, '.gitignore')) ? await maybeRead(resolve(path, '.gitignore'))
@ -66,7 +117,7 @@ async function npm(
const prefixLength = path.length + 1; const prefixLength = path.length + 1;
// the package.json `files` whitelist still // The package.json `files` whitelist still
// honors npmignores: https://docs.npmjs.com/files/package.json#files // honors npmignores: https://docs.npmjs.com/files/package.json#files
// but we don't ignore if the user is explicitly listing files // but we don't ignore if the user is explicitly listing files
// under the now namespace, or using files in combination with gitignore // under the now namespace, or using files in combination with gitignore
@ -88,7 +139,7 @@ async function npm(
return accepted; return accepted;
}; };
// locate files // Locate files
if (debug) { if (debug) {
console.time(`> [debug] locating files ${path}`); console.time(`> [debug] locating files ${path}`);
} }
@ -103,7 +154,7 @@ async function npm(
console.timeEnd(`> [debug] locating files ${path}`); console.timeEnd(`> [debug] locating files ${path}`);
} }
// always include manifest as npm does not allow ignoring it // Always include manifest as npm does not allow ignoring it
// source: https://docs.npmjs.com/files/package.json#files // source: https://docs.npmjs.com/files/package.json#files
files.push(asAbsolute('package.json', path)); files.push(asAbsolute('package.json', path));
@ -111,26 +162,10 @@ async function npm(
files.push(asAbsolute('now.json', path)); files.push(asAbsolute('now.json', path));
} }
// get files // Get files
return unique(files); return unique(files);
} }
/**
* 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 * Returns a list of files in the given
* directory that are subject to be * directory that are subject to be
@ -155,15 +190,15 @@ async function docker(
) { ) {
const whitelist = nowConfig && nowConfig.files; const whitelist = nowConfig && nowConfig.files;
// base search path // Base search path
// the now.json `files` whitelist still // the now.json `files` whitelist still
// honors ignores: https://docs.npmjs.com/files/package.json#files // honors ignores: https://docs.npmjs.com/files/package.json#files
const search_ = whitelist || ['.']; const search_ = whitelist || ['.'];
// convert all filenames into absolute paths // Convert all filenames into absolute paths
const search = search_.map(file => asAbsolute(file, path)); const search = search_.map(file => asAbsolute(file, path));
// compile list of ignored patterns and files // Compile list of ignored patterns and files
const dockerIgnore = await maybeRead(resolve(path, '.dockerignore'), null); const dockerIgnore = await maybeRead(resolve(path, '.dockerignore'), null);
const filter = ignore() const filter = ignore()
@ -193,7 +228,7 @@ async function docker(
return accepted; return accepted;
}; };
// locate files // Locate files
if (debug) { if (debug) {
console.time(`> [debug] locating files ${path}`); console.time(`> [debug] locating files ${path}`);
} }
@ -204,7 +239,7 @@ async function docker(
console.timeEnd(`> [debug] locating files ${path}`); console.timeEnd(`> [debug] locating files ${path}`);
} }
// always include manifest as npm does not allow ignoring it // Always include manifest as npm does not allow ignoring it
// source: https://docs.npmjs.com/files/package.json#files // source: https://docs.npmjs.com/files/package.json#files
files.push(asAbsolute('Dockerfile', path)); files.push(asAbsolute('Dockerfile', path));
@ -212,22 +247,10 @@ async function docker(
files.push(asAbsolute('now.json', path)); files.push(asAbsolute('now.json', path));
} }
// get files // Get files
return unique(files); return unique(files);
} }
const glob = async function(pattern, options) {
return new Promise((resolve, reject) => {
_glob(pattern, options, (error, files) => {
if (error) {
reject(error);
} else {
resolve(files);
}
});
});
};
/** /**
* Explodes directories into a full list of files. * Explodes directories into a full list of files.
* Eg: * Eg:
@ -254,7 +277,7 @@ async function explode(paths, { accepts, debug }) {
try { try {
s = await stat(path); s = await stat(path);
} catch (e) { } catch (e) {
// in case the file comes from `files` or `main` // In case the file comes from `files` or `main`
// and it wasn't specified with `.js` by the user // and it wasn't specified with `.js` by the user
path = file + '.js'; path = file + '.js';
@ -270,7 +293,9 @@ async function explode(paths, { accepts, debug }) {
if (s.isDirectory()) { if (s.isDirectory()) {
const all = await readdir(file); const all = await readdir(file);
/* eslint-disable no-use-before-define */
return many(all.map(subdir => asAbsolute(subdir, file))); return many(all.map(subdir => asAbsolute(subdir, file)));
/* eslint-enable no-use-before-define */
} else if (!s.isFile()) { } else if (!s.isFile()) {
if (debug) { if (debug) {
console.log('> [debug] ignoring special file "%s"', file); console.log('> [debug] ignoring special file "%s"', file);
@ -282,39 +307,19 @@ async function explode(paths, { accepts, debug }) {
}; };
const many = async all => { const many = async all => {
return await Promise.all( const awaitAll = await Promise.all(
all.map(async file => { all.map(async file => {
return await list(file); const listed = await list(file);
return listed;
}) })
); );
return awaitAll;
}; };
return flatten(await many(paths)).filter(v => v !== null); return flatten(await many(paths)).filter(v => v !== null);
} }
/**
* 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_;
}
};
/**
* Remove leading `./` from the beginning of ignores
* because our parser doesn't like them :|
*/
const clearRelative = function(str) {
return str.replace(/(\n|^)\.\//g, '$1');
};
module.exports = { module.exports = {
npm, npm,
docker docker

100
lib/git.js

@ -50,55 +50,6 @@ const renameRepoDir = async (pathParts, tmpDir) => {
return tmpDir; return tmpDir;
}; };
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) {
gitInstalled = false;
}
if (gitInstalled) {
return await renameRepoDir(pathParts, tmpDir);
}
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;
}
return await renameRepoDir(pathParts, tmpDir);
};
const capitalizePlatform = name => { const capitalizePlatform = name => {
const names = { const names = {
github: 'GitHub', github: 'GitHub',
@ -166,6 +117,57 @@ const gitPathParts = main => {
}; };
}; };
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) {
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 => { const isRepoPath = path => {
if (!path) { if (!path) {
return false; return false;

2
lib/ignored.js

@ -1,4 +1,4 @@
// base `.gitignore` to which we add entries // Base `.gitignore` to which we add entries
// supplied by the user // supplied by the user
module.exports = `.hg module.exports = `.hg
.git .git

41
lib/index.js

@ -19,11 +19,11 @@ const hash = require('./hash');
const Agent = require('./agent'); const Agent = require('./agent');
const readMetaData = require('./read-metadata'); const readMetaData = require('./read-metadata');
// how many concurrent HTTP/2 stream uploads // How many concurrent HTTP/2 stream uploads
const MAX_CONCURRENT = 10; const MAX_CONCURRENT = 10;
// check if running windows // Check if running windows
const IS_WIN = /^win/.test(process.platform); const IS_WIN = process.platform.startsWith('win');
const SEP = IS_WIN ? '\\' : '/'; const SEP = IS_WIN ? '\\' : '/';
module.exports = class Now extends EventEmitter { module.exports = class Now extends EventEmitter {
@ -138,7 +138,7 @@ module.exports = class Now extends EventEmitter {
Array.from(this._files).map(async ([sha, { data, names }]) => { Array.from(this._files).map(async ([sha, { data, names }]) => {
const statFn = followSymlinks ? stat : lstat; const statFn = followSymlinks ? stat : lstat;
return await names.map(async name => { const nameList = await names.map(async name => {
let mode; let mode;
const getMode = async () => { const getMode = async () => {
@ -164,6 +164,8 @@ module.exports = class Now extends EventEmitter {
mode mode
}; };
}); });
return nameList;
}) })
) )
) )
@ -189,7 +191,7 @@ module.exports = class Now extends EventEmitter {
console.timeEnd('> [debug] /now/create'); console.timeEnd('> [debug] /now/create');
} }
// no retry on 4xx // No retry on 4xx
let body; let body;
try { try {
body = await res.json(); body = await res.json();
@ -215,7 +217,7 @@ module.exports = class Now extends EventEmitter {
return body; return body;
}); });
// we report about files whose sizes are too big // We report about files whose sizes are too big
let missingVersion = false; let missingVersion = false;
if (deployment.warnings) { if (deployment.warnings) {
let sizeExceeded = 0; let sizeExceeded = 0;
@ -224,16 +226,16 @@ module.exports = class Now extends EventEmitter {
const { sha, limit } = warning; const { sha, limit } = warning;
const n = hashes.get(sha).names.pop(); const n = hashes.get(sha).names.pop();
console.error( console.error(
'> \u001b[31mWarning!\u001b[39m Skipping file %s (size exceeded %s)', '> \u001B[31mWarning!\u001B[39m Skipping file %s (size exceeded %s)',
n, n,
bytes(limit) bytes(limit)
); );
hashes.get(sha).names.unshift(n); // move name (hack, if duplicate matches we report them in order) hashes.get(sha).names.unshift(n); // Move name (hack, if duplicate matches we report them in order)
sizeExceeded++; sizeExceeded++;
} else if (warning.reason === 'node_version_not_found') { } else if (warning.reason === 'node_version_not_found') {
const { wanted, used } = warning; const { wanted, used } = warning;
console.error( console.error(
'> \u001b[31mWarning!\u001b[39m Requested node version %s is not available', '> \u001B[31mWarning!\u001B[39m Requested node version %s is not available',
wanted, wanted,
used used
); );
@ -243,7 +245,7 @@ module.exports = class Now extends EventEmitter {
if (sizeExceeded) { if (sizeExceeded) {
console.error( console.error(
`> \u001b[31mWarning!\u001b[39m ${sizeExceeded} of the files ` + `> \u001B[31mWarning!\u001B[39m ${sizeExceeded} of the files ` +
'exceeded the limit for your plan.\n' + 'exceeded the limit for your plan.\n' +
`> Please run ${chalk.gray('`')}${chalk.cyan('now upgrade')}${chalk.gray('`')} to upgrade.` `> Please run ${chalk.gray('`')}${chalk.cyan('now upgrade')}${chalk.gray('`')} to upgrade.`
); );
@ -334,7 +336,7 @@ module.exports = class Now extends EventEmitter {
); );
} }
// no retry on 4xx // No retry on 4xx
if ( if (
res.status !== 200 && (res.status >= 400 || res.status < 500) res.status !== 200 && (res.status >= 400 || res.status < 500)
) { ) {
@ -392,7 +394,7 @@ module.exports = class Now extends EventEmitter {
console.timeEnd('> [debug] /list'); console.timeEnd('> [debug] /list');
} }
// no retry on 4xx // No retry on 4xx
if (res.status >= 400 && res.status < 500) { if (res.status >= 400 && res.status < 500) {
if (this._debug) { if (this._debug) {
console.log('> [debug] bailing on listing due to %s', res.status); console.log('> [debug] bailing on listing due to %s', res.status);
@ -471,7 +473,8 @@ module.exports = class Now extends EventEmitter {
console.timeEnd(`> [debug] #${attempt} GET /domains/${domain}`); console.timeEnd(`> [debug] #${attempt} GET /domains/${domain}`);
} }
return await res.json(); const parsedJSON = await res.json();
return parsedJSON;
}); });
} }
@ -502,7 +505,7 @@ module.exports = class Now extends EventEmitter {
if ( if (
(!body.nameservers || body.nameservers.length === 0) && !fallback (!body.nameservers || body.nameservers.length === 0) && !fallback
) { ) {
// if the nameservers are `null` it's likely // If the nameservers are `null` it's likely
// that our whois service failed to parse it // that our whois service failed to parse it
fallback = true; fallback = true;
throw new Error('Invalid whois response'); throw new Error('Invalid whois response');
@ -519,7 +522,7 @@ module.exports = class Now extends EventEmitter {
}) })
.then(body => { .then(body => {
body.nameservers = body.nameservers.filter(ns => { body.nameservers = body.nameservers.filter(ns => {
// temporary hack: // Temporary hack:
// sometimes we get a response that looks like: // sometimes we get a response that looks like:
// ['ns', 'ns', '', ''] // ['ns', 'ns', '', '']
// so we filter the empty ones // so we filter the empty ones
@ -566,7 +569,7 @@ module.exports = class Now extends EventEmitter {
err.userError = true; err.userError = true;
return bail(err); return bail(err);
} else if (res.status === 409) { } else if (res.status === 409) {
// domain already exists // Domain already exists
if (this._debug) { if (this._debug) {
console.log('> [debug] Domain already exists (noop)'); console.log('> [debug] Domain already exists (noop)');
} }
@ -623,12 +626,12 @@ module.exports = class Now extends EventEmitter {
'This likely has to do with DNS propagation and caching issues. Please retry later!' 'This likely has to do with DNS propagation and caching issues. Please retry later!'
); );
err.userError = true; err.userError = true;
// retry // Retry
throw err; throw err;
} else if (code === 'rate_limited') { } else if (code === 'rate_limited') {
const err = new Error(body.error.message); const err = new Error(body.error.message);
err.userError = true; err.userError = true;
// dont retry // Dont retry
return bail(err); return bail(err);
} }
@ -684,7 +687,7 @@ module.exports = class Now extends EventEmitter {
console.timeEnd('> [debug] /remove'); console.timeEnd('> [debug] /remove');
} }
// no retry on 4xx // No retry on 4xx
if (res.status >= 400 && res.status < 500) { if (res.status >= 400 && res.status < 500) {
if (this._debug) { if (this._debug) {
console.log('> [debug] bailing on removal due to %s', res.status); console.log('> [debug] bailing on removal due to %s', res.status);

2
lib/login.js

@ -102,6 +102,7 @@ async function register(url, { retryEmail = false } = {}) {
let final; let final;
/* eslint-disable no-await-in-loop */
do { do {
await sleep(2500); await sleep(2500);
@ -109,6 +110,7 @@ async function register(url, { retryEmail = false } = {}) {
final = await verify(url, email, token); final = await verify(url, email, token);
} catch (err) {} } catch (err) {}
} while (!final); } while (!final);
/* eslint-enable no-await-in-loop */
spinner.text = 'Confirmed email address!'; spinner.text = 'Confirmed email address!';
spinner.stopAndPersist('✔'); spinner.stopAndPersist('✔');

2
lib/logs.js

@ -1,6 +1,6 @@
exports.compare = function(a, b) { exports.compare = function(a, b) {
return a.serial.localeCompare(b.serial) || return a.serial.localeCompare(b.serial) ||
// for the case serials are a same value on old logs // For the case serials are a same value on old logs
a.created.getTime() - b.created.getTime(); a.created.getTime() - b.created.getTime();
}; };

2
lib/pkg.js

@ -1,3 +1,5 @@
/* eslint-disable import/no-unresolved */
let pkg; let pkg;
try { try {
pkg = require('../package.json'); pkg = require('../package.json');

7
lib/plans.js

@ -28,7 +28,8 @@ module.exports = class Plans extends Now {
async getCurrent() { async getCurrent() {
const res = await this._fetch('/www/user/plan'); const res = await this._fetch('/www/user/plan');
return await parsePlan(res); const parsedPlan = await parsePlan(res);
return parsedPlan;
} }
async set(plan) { async set(plan) {
@ -38,8 +39,10 @@ module.exports = class Plans extends Now {
}); });
if (res.ok) { if (res.ok) {
return await parsePlan(res); const parsedPlan = await parsePlan(res);
return parsedPlan;
} }
const err = new Error(res.statusText); const err = new Error(res.statusText);
err.res = res; err.res = res;
throw err; throw err;

8
lib/re-alias.js

@ -36,7 +36,7 @@ exports.reAlias = async (token, host, help, exit, apiUrl, debug, alias) => {
} }
const { nowConfig, name } = await readMetaData(path, { const { nowConfig, name } = await readMetaData(path, {
deploymentType: 'npm', // hard coding settings… deploymentType: 'npm', // Hard coding settings…
quiet: true // `quiet` quiet: true // `quiet`
}); });
@ -80,7 +80,11 @@ exports.reAlias = async (token, host, help, exit, apiUrl, debug, alias) => {
return exit(0); return exit(0);
} }
const assignments = [];
for (const pointer of pointers) { for (const pointer of pointers) {
await exports.assignAlias(pointer, token, host, apiUrl, debug); assignments.push(exports.assignAlias(pointer, token, host, apiUrl, debug));
} }
await Promise.all(assignments);
}; };

8
lib/read-metadata.js

@ -35,7 +35,7 @@ async function readMetaData(
nowConfig = JSON.parse(await readFile(resolvePath(path, 'now.json'))); nowConfig = JSON.parse(await readFile(resolvePath(path, 'now.json')));
hasNowJson = true; hasNowJson = true;
} catch (err) { } catch (err) {
// if the file doesn't exist then that's fine; any other error bubbles up // If the file doesn't exist then that's fine; any other error bubbles up
if (err.code !== 'ENOENT') { if (err.code !== 'ENOENT') {
const e = Error(`Failed to read JSON in "${path}/now.json"`); const e = Error(`Failed to read JSON in "${path}/now.json"`);
e.userError = true; e.userError = true;
@ -44,7 +44,7 @@ async function readMetaData(
} }
if (hasNowJson) { if (hasNowJson) {
// user can specify the type of deployment explicitly in the `now.json` file // User can specify the type of deployment explicitly in the `now.json` file
// when both a package.json and Dockerfile exist // when both a package.json and Dockerfile exist
if (nowConfig.type) { if (nowConfig.type) {
deploymentType = nowConfig.type; deploymentType = nowConfig.type;
@ -131,7 +131,7 @@ async function readMetaData(
continue; continue;
} }
// unescape and convert into string // Unescape and convert into string
try { try {
labels[key] = JSON.parse(args[key]); labels[key] = JSON.parse(args[key]);
} catch (err) { } catch (err) {
@ -174,7 +174,7 @@ async function readMetaData(
} }
if (pkg.now) { if (pkg.now) {
// if the project has both a `now.json` and `now` Object in the `package.json` // 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 // file, then fail hard and let the user know that they need to pick one or the
// other // other
if (hasNowJson) { if (hasNowJson) {

2
lib/strlen.js

@ -1,5 +1,5 @@
function strlen(str) { function strlen(str) {
return str.replace(/\x1b[^m]*m/g, '').length; return str.replace(/\u001b[^m]*m/g, '').length;
} }
module.exports = strlen; module.exports = strlen;

2
lib/to-host.js

@ -12,7 +12,7 @@ function toHost(url) {
return parse(url).host; return parse(url).host;
} }
// remove any path if present // Remove any path if present
// `a.b.c/` => `a.b.c` // `a.b.c/` => `a.b.c`
return url.replace(/(\/\/)?([^/]+)(.*)/, '$2'); return url.replace(/(\/\/)?([^/]+)(.*)/, '$2');
} }

2
lib/utils/exit.js

@ -1,5 +1,5 @@
module.exports = code => { module.exports = code => {
// we give stdout some time to flush out // We give stdout some time to flush out
// because there's a node bug where // because there's a node bug where
// stdout writes are asynchronous // stdout writes are asynchronous
// https://github.com/nodejs/node/issues/6456 // https://github.com/nodejs/node/issues/6456

4
lib/utils/input/list.js

@ -39,8 +39,8 @@ module.exports = async function(
} }
], ],
pageSize = 15, // Show 15 lines without scrolling (~4 credit cards) pageSize = 15, // Show 15 lines without scrolling (~4 credit cards)
separator = true, // puts a blank separator between each choice separator = true, // Puts a blank separator between each choice
abort = 'end' // wether the `abort` option will be at the `start` or the `end` abort = 'end' // Wether the `abort` option will be at the `start` or the `end`
} }
) { ) {
let biggestLength = 0; let biggestLength = 0;

2
lib/utils/input/prompt-bool.js

@ -4,7 +4,7 @@ module.exports = (
label, label,
{ {
defaultValue = false, defaultValue = false,
abortSequences = new Set(['\x03']), abortSequences = new Set(['\u0003']),
resolveChars = new Set(['\r']), resolveChars = new Set(['\r']),
yesChar = 'y', yesChar = 'y',
noChar = 'n', noChar = 'n',

20
lib/utils/input/text.js

@ -4,11 +4,11 @@ const chalk = require('chalk');
const stripAnsi = require('strip-ansi'); const stripAnsi = require('strip-ansi');
const ESCAPES = { const ESCAPES = {
LEFT: '\x1b[D', LEFT: '\u001B[D',
RIGHT: '\x1b[C', RIGHT: '\u001B[C',
CTRL_C: '\x03', CTRL_C: '\u0003',
BACKSPACE: '\x08', BACKSPACE: '\u0008',
CTRL_H: '\x7f', CTRL_H: '\u007F',
CARRIAGE: '\r' CARRIAGE: '\r'
}; };
@ -16,21 +16,21 @@ module.exports = function(
{ {
label = '', label = '',
initialValue = '', initialValue = '',
// can be: // Can be:
// - `false`, which does nothing // - `false`, which does nothing
// - `cc`, for credit cards // - `cc`, for credit cards
// - `date`, for dates in the mm / yyyy format // - `date`, for dates in the mm / yyyy format
mask = false, mask = false,
placeholder = '', placeholder = '',
abortSequences = new Set(['\x03']), abortSequences = new Set(['\u0003']),
eraseSequences = new Set([ESCAPES.BACKSPACE, ESCAPES.CTRL_H]), eraseSequences = new Set([ESCAPES.BACKSPACE, ESCAPES.CTRL_H]),
resolveChars = new Set([ESCAPES.CARRIAGE]), resolveChars = new Set([ESCAPES.CARRIAGE]),
stdin = process.stdin, stdin = process.stdin,
stdout = process.stdout, stdout = process.stdout,
// char to print before resolving/rejecting the promise // Char to print before resolving/rejecting the promise
// if `false`, nothing will be printed // if `false`, nothing will be printed
trailing = ansiEscapes.eraseLines(1), trailing = ansiEscapes.eraseLines(1),
// gets called on each keypress; // Gets called on each keypress;
// `data` contains the current keypress; // `data` contains the current keypress;
// `futureValue` contains the current value + the // `futureValue` contains the current value + the
// keypress in the correct place // keypress in the correct place
@ -43,7 +43,7 @@ module.exports = function(
autoComplete = value => false, // eslint-disable-line no-unused-vars autoComplete = value => false, // eslint-disable-line no-unused-vars
// tab // tab
// right arrow // right arrow
autoCompleteChars = new Set(['\t', '\x1b[C']) autoCompleteChars = new Set(['\t', '\u001B[C'])
} = {} } = {}
) { ) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {

2
lib/utils/output/cmd.js

@ -1,6 +1,6 @@
const chalk = require('chalk'); const chalk = require('chalk');
// the equivalent of <code>, for embedding a cmd // The equivalent of <code>, for embedding a cmd
// eg: Please run ${cmd(woot)} // eg: Please run ${cmd(woot)}
module.exports = cmd => module.exports = cmd =>

2
lib/utils/output/code.js

@ -1,6 +1,6 @@
const chalk = require('chalk'); const chalk = require('chalk');
// the equivalent of <code>, for embedding anything // The equivalent of <code>, for embedding anything
// you may want to take a look at ./cmd.js // you may want to take a look at ./cmd.js
module.exports = cmd => module.exports = cmd =>

2
lib/utils/output/error.js

@ -1,6 +1,6 @@
const chalk = require('chalk'); const chalk = require('chalk');
// prints an error message // Prints an error message
module.exports = msg => { module.exports = msg => {
console.error(`${chalk.red('> Error!')} ${msg}`); console.error(`${chalk.red('> Error!')} ${msg}`);
}; };

2
lib/utils/output/info.js

@ -1,6 +1,6 @@
const chalk = require('chalk'); const chalk = require('chalk');
// prints an informational message // Prints an informational message
module.exports = msg => { module.exports = msg => {
console.log(`${chalk.gray('>')} ${msg}`); console.log(`${chalk.gray('>')} ${msg}`);
}; };

2
lib/utils/output/param.js

@ -1,6 +1,6 @@
const chalk = require('chalk'); const chalk = require('chalk');
// returns a user param in a nice formatting // Returns a user param in a nice formatting
// e.g.: google.com -> "google.com" (in bold) // e.g.: google.com -> "google.com" (in bold)
module.exports = param => module.exports = param =>

2
lib/utils/output/stamp.js

@ -1,7 +1,7 @@
const ms = require('ms'); const ms = require('ms');
const chalk = require('chalk'); const chalk = require('chalk');
// returns a time delta with the right color // Returns a time delta with the right color
// example: `[103ms]` // example: `[103ms]`
module.exports = () => { module.exports = () => {

2
lib/utils/output/success.js

@ -1,6 +1,6 @@
const chalk = require('chalk'); const chalk = require('chalk');
// prints a success message // Prints a success message
module.exports = msg => { module.exports = msg => {
console.log(`${chalk.cyan('> Success!')} ${msg}`); console.log(`${chalk.cyan('> Success!')} ${msg}`);
}; };

2
lib/utils/output/uid.js

@ -1,5 +1,5 @@
const chalk = require('chalk'); const chalk = require('chalk');
// used for including uids in the output // Used for including uids in the output
// example: `(dom_ji13dj2fih4fi2hf)` // example: `(dom_ji13dj2fih4fi2hf)`
module.exports = id => chalk.gray(`(${id})`); module.exports = id => chalk.gray(`(${id})`);

2
lib/utils/output/wait.js

@ -2,7 +2,7 @@ const ora = require('ora');
const chalk = require('chalk'); const chalk = require('chalk');
const { eraseLine } = require('ansi-escapes'); const { eraseLine } = require('ansi-escapes');
// prints a spinner followed by the given text // Prints a spinner followed by the given text
module.exports = msg => { module.exports = msg => {
const spinner = ora(chalk.gray(msg)); const spinner = ora(chalk.gray(msg));
spinner.color = 'gray'; spinner.color = 'gray';

2
lib/utils/to-human-path.js

@ -2,7 +2,7 @@
const { resolve } = require('path'); const { resolve } = require('path');
const { homedir } = require('os'); const { homedir } = require('os');
// cleaned-up `$HOME` (i.e.: no trailing slash) // Cleaned-up `$HOME` (i.e.: no trailing slash)
const HOME = resolve(homedir()); const HOME = resolve(homedir());
/** /**

29
package.json

@ -9,7 +9,7 @@
], ],
"scripts": { "scripts": {
"precommit": "lint-staged", "precommit": "lint-staged",
"lint": "eslint lib/* bin/*", "lint": "xo",
"test": "npm run build && npm run lint && ava", "test": "npm run build && npm run lint && ava",
"prepublish": "npm run build", "prepublish": "npm run build",
"build": "./build.sh", "build": "./build.sh",
@ -30,20 +30,14 @@
"test/*.js" "test/*.js"
] ]
}, },
"eslintConfig": { "xo": {
"parserOptions": { "space": true,
"ecmaVersion": 8 "ignores": [
}, "test/_fixtures/**"
"extends": "eslint:recommended", ],
"env": { "extends": [
"node": true, "prettier"
"es6": true ]
},
"rules": {
"no-console": 0,
"no-empty": 0,
"no-control-regex": 0
}
}, },
"lint-staged": { "lint-staged": {
"*.js": [ "*.js": [
@ -99,9 +93,10 @@
"devDependencies": { "devDependencies": {
"alpha-sort": "2.0.0", "alpha-sort": "2.0.0",
"ava": "0.18.2", "ava": "0.18.2",
"eslint": "3.18.0", "eslint-config-prettier": "1.5.0",
"husky": "0.13.3-0", "husky": "0.13.3-0",
"lint-staged": "3.4.0", "lint-staged": "3.4.0",
"pkg": "3.0.0-beta.29" "pkg": "3.0.0-beta.29",
"xo": "0.18.0"
} }
} }

1
readme.md

@ -1,6 +1,7 @@
# now CLI # now CLI
[![Build Status](https://travis-ci.org/zeit/now-cli.svg?branch=master)](https://travis-ci.org/zeit/now-cli) [![Build Status](https://travis-ci.org/zeit/now-cli.svg?branch=master)](https://travis-ci.org/zeit/now-cli)
[![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/sindresorhus/xo)
[![Slack Channel](https://zeit-slackin.now.sh/badge.svg)](https://zeit.chat) [![Slack Channel](https://zeit-slackin.now.sh/badge.svg)](https://zeit.chat)
Realtime global deployments served over HTTP/2. You can find the FAQs [here](https://zeit.co/now#frequently-asked-questions). Realtime global deployments served over HTTP/2. You can find the FAQs [here](https://zeit.co/now#frequently-asked-questions).

2
test/index.js

@ -17,7 +17,7 @@ const prefix = join(__dirname, '_fixtures') + '/';
const base = path => path.replace(prefix, ''); const base = path => path.replace(prefix, '');
const fixture = name => resolve(`./test/_fixtures/${name}`); const fixture = name => resolve(`./test/_fixtures/${name}`);
// overload to force debugging // Overload to force debugging
const getNpmFiles = async dir => { const getNpmFiles = async dir => {
const { pkg, nowConfig, hasNowJson } = await readMetadata(dir, { const { pkg, nowConfig, hasNowJson } = await readMetadata(dir, {
quiet: true, quiet: true,

12
test/to-host.js

@ -1,38 +1,38 @@
const test = require('ava'); const test = require('ava');
const toHost = require('../build/lib/to-host'); const toHost = require('../build/lib/to-host');
test('simple', async t => { test('simple', t => {
t.is(toHost('zeit.co'), 'zeit.co'); t.is(toHost('zeit.co'), 'zeit.co');
}); });
test('leading //', async t => { test('leading //', t => {
t.is( t.is(
toHost('//zeit-logos-rnemgaicnc.now.sh'), toHost('//zeit-logos-rnemgaicnc.now.sh'),
'zeit-logos-rnemgaicnc.now.sh' 'zeit-logos-rnemgaicnc.now.sh'
); );
}); });
test('leading http://', async t => { test('leading http://', t => {
t.is( t.is(
toHost('http://zeit-logos-rnemgaicnc.now.sh'), toHost('http://zeit-logos-rnemgaicnc.now.sh'),
'zeit-logos-rnemgaicnc.now.sh' 'zeit-logos-rnemgaicnc.now.sh'
); );
}); });
test('leading https://', async t => { test('leading https://', t => {
t.is( t.is(
toHost('https://zeit-logos-rnemgaicnc.now.sh'), toHost('https://zeit-logos-rnemgaicnc.now.sh'),
'zeit-logos-rnemgaicnc.now.sh' 'zeit-logos-rnemgaicnc.now.sh'
); );
}); });
test('leading https:// and path', async t => { test('leading https:// and path', t => {
t.is( t.is(
toHost('https://zeit-logos-rnemgaicnc.now.sh/path'), toHost('https://zeit-logos-rnemgaicnc.now.sh/path'),
'zeit-logos-rnemgaicnc.now.sh' 'zeit-logos-rnemgaicnc.now.sh'
); );
}); });
test('simple and path', async t => { test('simple and path', t => {
t.is(toHost('zeit.co/test'), 'zeit.co'); t.is(toHost('zeit.co/test'), 'zeit.co');
}); });

Loading…
Cancel
Save