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. 45
      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];
// options
// Options
const help = () => {
console.log(
`
@ -92,7 +92,7 @@ const help = () => {
);
};
// options
// Options
const debug = argv.debug;
const apiUrl = argv.url || 'https://api.zeit.co';
@ -211,7 +211,7 @@ async function run(token) {
);
return [
'',
// we default to `''` because some early aliases didn't
// We default to `''` because some early aliases didn't
// have an uid associated
_alias.uid === null ? '' : _alias.uid,
_sourceUrl,
@ -342,7 +342,9 @@ async function confirmDeploymentRemoval(alias, _alias) {
const msg = '> The following alias will be removed permanently\n' +
` ${tbl} \nAre you sure?`;
return await promptBool(msg);
const prompted = await promptBool(msg);
return prompted;
}
function findAlias(alias, list) {
@ -366,7 +368,7 @@ function findAlias(alias, list) {
return true;
}
// match prefix
// Match prefix
if (`${val}.now.sh` === d.alias) {
if (debug) {
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') {
let result;
try {
/* eslint-disable no-await-in-loop */
result = await textInput({
label: '- ' + piece.label,
initialValue: piece.initialValue || piece.value,
@ -126,7 +127,9 @@ module.exports = function(creditCards) {
validateValue: piece.validateValue,
autoComplete: piece.autoComplete
});
piece.value = result;
if (key === 'cardNumber') {
let brand = cardBrands[ccValidator.determineCardType(result)];
piece.brand = brand;
@ -178,7 +181,7 @@ module.exports = function(creditCards) {
}
}
}
console.log(''); // new line
console.log(''); // New line
const stopSpinner = wait('Saving card');
try {

4
bin/now-billing.js

@ -69,7 +69,7 @@ const help = () => {
);
};
// options
// Options
const debug = argv.debug;
const apiUrl = argv.url || 'https://api.zeit.co';
@ -78,7 +78,7 @@ if (argv.config) {
}
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
// stdout writes are asynchronous
// 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];
// options
// Options
const help = () => {
console.log(
`
@ -73,7 +73,7 @@ const help = () => {
);
};
// options
// Options
const debug = argv.debug;
const apiUrl = argv.url || 'https://api.zeit.co';

22
bin/now-deploy.js

@ -146,7 +146,7 @@ const help = () => {
let path = argv._[0];
if (path) {
// if path is relative: resolve
// If path is relative: resolve
// if path is absolute: clear up strange `/` etc
path = resolve(process.cwd(), path);
} else {
@ -156,7 +156,7 @@ if (path) {
// If the current deployment is a repo
const gitRepo = {};
// options
// Options
let forceNew = argv.force;
const debug = argv.debug;
const clipboard = !argv['no-clipboard'];
@ -483,7 +483,7 @@ async function sync(token) {
console.log(
`> 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(/^@/, '\\@');
} else {
error(
@ -585,10 +585,10 @@ async function sync(token) {
console.log('> Initializing…');
}
// close http2 agent
// Close http2 agent
now.close();
// show build logs
// Show build logs
printLogs(now.host, token);
};
@ -624,16 +624,16 @@ async function sync(token) {
console.log(`> Initializing…`);
}
// close http2 agent
// Close http2 agent
now.close();
// show build logs
// Show build logs
printLogs(now.host, token);
}
}
function printLogs(host, token) {
// log build
// Log build
const logger = new Logger(host, { debug, quiet });
logger.on('error', async err => {
@ -663,9 +663,13 @@ function printLogs(host, token) {
const aliasList = autoAliases.filter(item => item !== '');
if (aliasList.length > 0) {
const assignments = [];
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 {
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];
// options
// Options
const help = () => {
console.log(
`
@ -65,7 +65,7 @@ const help = () => {
);
};
// options
// Options
const debug = argv.debug;
const apiUrl = argv.url || 'https://api.zeit.co';
if (argv.config) {

6
bin/now-domains.js

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

2
bin/now-open.js

@ -53,7 +53,7 @@ if (argv.help) {
const app = argv._[0];
// options
// Options
const debug = argv.debug;
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._;
// options
// Options
const help = () => {
console.log(
`
@ -66,7 +66,7 @@ if (argv.help || ids.length === 0) {
process.exit(0);
}
// options
// Options
const debug = argv.debug;
const apiUrl = argv.url || 'https://api.zeit.co';
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];
// options
// Options
const help = () => {
console.log(
`
@ -74,7 +74,7 @@ const help = () => {
);
};
// options
// Options
const debug = argv.debug;
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 apiUrl = argv.url || 'https://api.zeit.co';
@ -67,7 +67,7 @@ if (argv.config) {
}
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
// stdout writes are asynchronous
// https://github.com/nodejs/node/issues/6456

4
lib/agent.js

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

37
lib/alias.js

@ -82,7 +82,7 @@ module.exports = class Alias extends Now {
return true;
}
// match prefix
// Match prefix
if (`${val}.now.sh` === d.url) {
if (this._debug) {
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) {
alias = await this.maybeSetUpDomain(alias);
const upsert = await this.upsertPathAlias(alias, rules);
return await this.upsertPathAlias(alias, rules);
return upsert;
}
async upsertPathAlias(alias, rules) {
@ -130,7 +131,7 @@ module.exports = class Alias extends Now {
return body;
}
// no retry on authorization problems
// No retry on authorization problems
if (res.status === 403) {
const code = body.error.code;
@ -161,7 +162,7 @@ module.exports = class Alias extends Now {
return bail(new Error('Authorization error'));
}
// all other errors
// All other errors
if (body.error) {
const code = body.error.code;
@ -173,13 +174,13 @@ module.exports = class Alias extends Now {
try {
await this.createCert(alias);
} 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
// retries on certificate provisioning
return bail(err);
}
// try again, but now having provisioned the certificate
// Try again, but now having provisioned the certificate
return this.upsertPathAlias(alias, rules);
}
@ -199,7 +200,7 @@ module.exports = class Alias extends Now {
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) {
throw new Error('Unhandled error');
}
@ -307,7 +308,7 @@ module.exports = class Alias extends Now {
return { uid: body.error.uid };
}
// no retry on authorization problems
// No retry on authorization problems
if (res.status === 403) {
const code = body.error.code;
@ -338,7 +339,7 @@ module.exports = class Alias extends Now {
return bail(new Error('Authorization error'));
}
// all other errors
// All other errors
if (body.error) {
const code = body.error.code;
@ -354,13 +355,13 @@ module.exports = class Alias extends Now {
try {
await this.createCert(alias);
} 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
// retries on certificate provisioning
return bail(err);
}
// try again, but now having provisioned the certificate
// Try again, but now having provisioned the certificate
return this.createAlias(depl, alias);
}
@ -379,7 +380,7 @@ module.exports = class Alias extends Now {
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) {
throw new Error('Unhandled error');
}
@ -429,13 +430,13 @@ module.exports = class Alias extends Now {
}
async maybeSetUpDomain(alias) {
// make alias lowercase
// Make alias lowercase
alias = alias.toLowerCase();
// trim leading and trailing dots
// Trim leading and trailing dots
// for example: `google.com.` => `google.com`
alias = alias.replace(/^\.+/, '').replace(/\.+$/, '');
// evaluate the alias
// Evaluate the alias
if (/\./.test(alias)) {
alias = toHost(alias);
} else {
@ -511,7 +512,7 @@ module.exports = class Alias extends Now {
}
} catch (err) {
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
// configuration (if we can!)
try {
@ -521,7 +522,7 @@ module.exports = class Alias extends Now {
);
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 _domain = domain.replace(/^\./, '').replace(/\.$/, '');
@ -615,7 +616,7 @@ module.exports = class Alias extends Now {
err.code === 'ESERVFAIL' ||
err.code === 'ENOTFOUND'
) {
// not errors per se, just absence of records
// Not errors per se, just absence of records
if (this._debug) {
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.quiet = quiet;
// readyState
// ReadyState
this.building = false;
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);
// log buffer
// Log buffer
this.buf = [];
}
onState(state) {
// console.log(state)
// Console.log(state)
if (!state.id) {
console.error('> Deployment not found');
this.emit('error');
@ -116,7 +116,7 @@ module.exports = class Logger extends EventEmitter {
this.buf.sort((a, b) => compare(a.log, b.log));
// flush all buffer
// Flush all buffer
for (const b of this.buf) {
clearTimeout(b.timer);
this.printLog(b.log);

8
lib/credit-cards.js

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

45
lib/domain-records.js

@ -29,28 +29,37 @@ module.exports = class DomainRecords extends Now {
}
const records = new Map();
const bodies = [];
for (const domain of domains) {
const body = await 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();
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;
})
);
}
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}"`);
}
const domainList = await Promise.all(bodies);
return body;
});
for (const body of domainList) {
records.set(
domain,
body,
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 {
async ls() {
return await this.listDomains();
const domains = await this.listDomains();
return domains;
}
async rm(name) {

143
lib/get-files.js

@ -11,6 +11,57 @@ const { stat, readdir, readFile } = require('fs-promise');
// 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
@ -36,10 +87,10 @@ async function npm(
) {
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
const search_ = whitelist || ['.'];
// convert all filenames into absolute paths
// Convert all filenames into absolute paths
const search = Array.prototype.concat.apply(
[],
await Promise.all(
@ -47,12 +98,12 @@ async function npm(
)
);
// always include the "main" file
// Always include the "main" file
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 gitIgnore = npmIgnore === null
? await maybeRead(resolve(path, '.gitignore'))
@ -66,7 +117,7 @@ async function npm(
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
// but we don't ignore if the user is explicitly listing files
// under the now namespace, or using files in combination with gitignore
@ -88,7 +139,7 @@ async function npm(
return accepted;
};
// locate files
// Locate files
if (debug) {
console.time(`> [debug] locating files ${path}`);
}
@ -103,7 +154,7 @@ async function npm(
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
files.push(asAbsolute('package.json', path));
@ -111,26 +162,10 @@ async function npm(
files.push(asAbsolute('now.json', path));
}
// get files
// Get 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
* directory that are subject to be
@ -155,15 +190,15 @@ async function docker(
) {
const whitelist = nowConfig && nowConfig.files;
// base search path
// 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
// Convert all filenames into absolute paths
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 filter = ignore()
@ -193,7 +228,7 @@ async function docker(
return accepted;
};
// locate files
// Locate files
if (debug) {
console.time(`> [debug] locating files ${path}`);
}
@ -204,7 +239,7 @@ async function docker(
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
files.push(asAbsolute('Dockerfile', path));
@ -212,22 +247,10 @@ async function docker(
files.push(asAbsolute('now.json', path));
}
// get files
// Get 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.
* Eg:
@ -254,7 +277,7 @@ async function explode(paths, { accepts, debug }) {
try {
s = await stat(path);
} 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
path = file + '.js';
@ -270,7 +293,9 @@ async function explode(paths, { accepts, debug }) {
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);
@ -282,39 +307,19 @@ async function explode(paths, { accepts, debug }) {
};
const many = async all => {
return await Promise.all(
const awaitAll = await Promise.all(
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);
}
/**
* 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 = {
npm,
docker

100
lib/git.js

@ -50,55 +50,6 @@ const renameRepoDir = async (pathParts, 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 names = {
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 => {
if (!path) {
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
module.exports = `.hg
.git

41
lib/index.js

@ -19,11 +19,11 @@ const hash = require('./hash');
const Agent = require('./agent');
const readMetaData = require('./read-metadata');
// how many concurrent HTTP/2 stream uploads
// How many concurrent HTTP/2 stream uploads
const MAX_CONCURRENT = 10;
// check if running windows
const IS_WIN = /^win/.test(process.platform);
// Check if running windows
const IS_WIN = process.platform.startsWith('win');
const SEP = IS_WIN ? '\\' : '/';
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 }]) => {
const statFn = followSymlinks ? stat : lstat;
return await names.map(async name => {
const nameList = await names.map(async name => {
let mode;
const getMode = async () => {
@ -164,6 +164,8 @@ module.exports = class Now extends EventEmitter {
mode
};
});
return nameList;
})
)
)
@ -189,7 +191,7 @@ module.exports = class Now extends EventEmitter {
console.timeEnd('> [debug] /now/create');
}
// no retry on 4xx
// No retry on 4xx
let body;
try {
body = await res.json();
@ -215,7 +217,7 @@ module.exports = class Now extends EventEmitter {
return body;
});
// we report about files whose sizes are too big
// We report about files whose sizes are too big
let missingVersion = false;
if (deployment.warnings) {
let sizeExceeded = 0;
@ -224,16 +226,16 @@ module.exports = class Now extends EventEmitter {
const { sha, limit } = warning;
const n = hashes.get(sha).names.pop();
console.error(
'> \u001b[31mWarning!\u001b[39m Skipping file %s (size exceeded %s)',
'> \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)
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',
'> \u001B[31mWarning!\u001B[39m Requested node version %s is not available',
wanted,
used
);
@ -243,7 +245,7 @@ module.exports = class Now extends EventEmitter {
if (sizeExceeded) {
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' +
`> 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 (
res.status !== 200 && (res.status >= 400 || res.status < 500)
) {
@ -392,7 +394,7 @@ module.exports = class Now extends EventEmitter {
console.timeEnd('> [debug] /list');
}
// no retry on 4xx
// 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);
@ -471,7 +473,8 @@ module.exports = class Now extends EventEmitter {
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 (
(!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
fallback = true;
throw new Error('Invalid whois response');
@ -519,7 +522,7 @@ module.exports = class Now extends EventEmitter {
})
.then(body => {
body.nameservers = body.nameservers.filter(ns => {
// temporary hack:
// Temporary hack:
// sometimes we get a response that looks like:
// ['ns', 'ns', '', '']
// so we filter the empty ones
@ -566,7 +569,7 @@ module.exports = class Now extends EventEmitter {
err.userError = true;
return bail(err);
} else if (res.status === 409) {
// domain already exists
// Domain already exists
if (this._debug) {
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!'
);
err.userError = true;
// retry
// Retry
throw err;
} else if (code === 'rate_limited') {
const err = new Error(body.error.message);
err.userError = true;
// dont retry
// Dont retry
return bail(err);
}
@ -684,7 +687,7 @@ module.exports = class Now extends EventEmitter {
console.timeEnd('> [debug] /remove');
}
// no retry on 4xx
// 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);

2
lib/login.js

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

2
lib/logs.js

@ -1,6 +1,6 @@
exports.compare = function(a, b) {
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();
};

2
lib/pkg.js

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

7
lib/plans.js

@ -28,7 +28,8 @@ module.exports = class Plans extends Now {
async getCurrent() {
const res = await this._fetch('/www/user/plan');
return await parsePlan(res);
const parsedPlan = await parsePlan(res);
return parsedPlan;
}
async set(plan) {
@ -38,8 +39,10 @@ module.exports = class Plans extends Now {
});
if (res.ok) {
return await parsePlan(res);
const parsedPlan = await parsePlan(res);
return parsedPlan;
}
const err = new Error(res.statusText);
err.res = res;
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, {
deploymentType: 'npm', // hard coding settings…
deploymentType: 'npm', // Hard coding settings…
quiet: true // `quiet`
});
@ -80,7 +80,11 @@ exports.reAlias = async (token, host, help, exit, apiUrl, debug, alias) => {
return exit(0);
}
const assignments = [];
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')));
hasNowJson = true;
} 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') {
const e = Error(`Failed to read JSON in "${path}/now.json"`);
e.userError = true;
@ -44,7 +44,7 @@ async function readMetaData(
}
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
if (nowConfig.type) {
deploymentType = nowConfig.type;
@ -131,7 +131,7 @@ async function readMetaData(
continue;
}
// unescape and convert into string
// Unescape and convert into string
try {
labels[key] = JSON.parse(args[key]);
} catch (err) {
@ -174,7 +174,7 @@ async function readMetaData(
}
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
// other
if (hasNowJson) {

2
lib/strlen.js

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

2
lib/to-host.js

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

2
lib/utils/exit.js

@ -1,5 +1,5 @@
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
// stdout writes are asynchronous
// 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)
separator = true, // puts a blank separator between each choice
abort = 'end' // wether the `abort` option will be at the `start` or the `end`
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;

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

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

20
lib/utils/input/text.js

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

2
lib/utils/output/cmd.js

@ -1,6 +1,6 @@
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)}
module.exports = cmd =>

2
lib/utils/output/code.js

@ -1,6 +1,6 @@
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
module.exports = cmd =>

2
lib/utils/output/error.js

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

2
lib/utils/output/info.js

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

2
lib/utils/output/param.js

@ -1,6 +1,6 @@
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)
module.exports = param =>

2
lib/utils/output/stamp.js

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

2
lib/utils/output/success.js

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

2
lib/utils/output/uid.js

@ -1,5 +1,5 @@
const chalk = require('chalk');
// used for including uids in the output
// Used for including uids in the output
// example: `(dom_ji13dj2fih4fi2hf)`
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 { eraseLine } = require('ansi-escapes');
// prints a spinner followed by the given text
// Prints a spinner followed by the given text
module.exports = msg => {
const spinner = ora(chalk.gray(msg));
spinner.color = 'gray';

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

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

29
package.json

@ -9,7 +9,7 @@
],
"scripts": {
"precommit": "lint-staged",
"lint": "eslint lib/* bin/*",
"lint": "xo",
"test": "npm run build && npm run lint && ava",
"prepublish": "npm run build",
"build": "./build.sh",
@ -30,20 +30,14 @@
"test/*.js"
]
},
"eslintConfig": {
"parserOptions": {
"ecmaVersion": 8
},
"extends": "eslint:recommended",
"env": {
"node": true,
"es6": true
},
"rules": {
"no-console": 0,
"no-empty": 0,
"no-control-regex": 0
}
"xo": {
"space": true,
"ignores": [
"test/_fixtures/**"
],
"extends": [
"prettier"
]
},
"lint-staged": {
"*.js": [
@ -99,9 +93,10 @@
"devDependencies": {
"alpha-sort": "2.0.0",
"ava": "0.18.2",
"eslint": "3.18.0",
"eslint-config-prettier": "1.5.0",
"husky": "0.13.3-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
[![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)
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 fixture = name => resolve(`./test/_fixtures/${name}`);
// overload to force debugging
// Overload to force debugging
const getNpmFiles = async dir => {
const { pkg, nowConfig, hasNowJson } = await readMetadata(dir, {
quiet: true,

12
test/to-host.js

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

Loading…
Cancel
Save