Leo Lamprecht
8 years ago
29 changed files with 1471 additions and 1167 deletions
@ -1,28 +1,29 @@ |
|||
import gulp from 'gulp'; |
|||
import del from 'del'; |
|||
import babel from 'gulp-babel'; |
|||
import help from 'gulp-task-listing'; |
|||
// Packages
|
|||
import gulp from 'gulp' |
|||
import del from 'del' |
|||
import babel from 'gulp-babel' |
|||
import help from 'gulp-task-listing' |
|||
|
|||
gulp.task('help', help); |
|||
gulp.task('help', help) |
|||
|
|||
gulp.task('compile', [ |
|||
'compile-lib', |
|||
'compile-bin' |
|||
]); |
|||
]) |
|||
|
|||
gulp.task('compile-lib', () => |
|||
gulp.src('lib/**/*.js') |
|||
.pipe(babel()) |
|||
.pipe(gulp.dest('build/lib'))); |
|||
.pipe(gulp.dest('build/lib'))) |
|||
|
|||
gulp.task('compile-bin', () => |
|||
gulp.src('bin/*') |
|||
.pipe(babel()) |
|||
.pipe(gulp.dest('build/bin'))); |
|||
.pipe(gulp.dest('build/bin'))) |
|||
|
|||
gulp.task('watch-lib', () => gulp.watch('lib/**/*.js', ['compile-lib'])); |
|||
gulp.task('watch-bin', () => gulp.watch('bin/*', ['compile-bin'])); |
|||
gulp.task('clean', () => del(['build'])); |
|||
gulp.task('watch-lib', () => gulp.watch('lib/**/*.js', ['compile-lib'])) |
|||
gulp.task('watch-bin', () => gulp.watch('bin/*', ['compile-bin'])) |
|||
gulp.task('clean', () => del(['build'])) |
|||
|
|||
gulp.task('watch', ['watch-lib', 'watch-bin']); |
|||
gulp.task('default', ['compile', 'watch']); |
|||
gulp.task('watch', ['watch-lib', 'watch-bin']) |
|||
gulp.task('default', ['compile', 'watch']) |
|||
|
@ -1,120 +1,121 @@ |
|||
import ansi from 'ansi-escapes'; |
|||
import io from 'socket.io-client'; |
|||
import chalk from 'chalk'; |
|||
import EventEmitter from 'events'; |
|||
// Native
|
|||
import EventEmitter from 'events' |
|||
|
|||
export default class Logger extends EventEmitter { |
|||
// Packages
|
|||
import ansi from 'ansi-escapes' |
|||
import io from 'socket.io-client' |
|||
import chalk from 'chalk' |
|||
|
|||
class Lines { |
|||
constructor(maxLines = 100) { |
|||
this.max = maxLines |
|||
this.buf = [] |
|||
} |
|||
|
|||
constructor (host, { debug = false, quiet = false } = {}) { |
|||
super(); |
|||
this.host = host; |
|||
this.debug = debug; |
|||
this.quiet = quiet; |
|||
write(str) { |
|||
const {max, buf} = this |
|||
|
|||
if (buf.length === max) { |
|||
process.stdout.write(ansi.eraseLines(max + 1)) |
|||
buf.shift() |
|||
buf.forEach(line => console.log(line)) |
|||
} |
|||
|
|||
buf.push(str) |
|||
console.log(str) |
|||
} |
|||
|
|||
reset() { |
|||
this.buf = [] |
|||
} |
|||
} |
|||
|
|||
export default class Logger extends EventEmitter { |
|||
constructor(host, {debug = false, quiet = false} = {}) { |
|||
super() |
|||
this.host = host |
|||
this.debug = debug |
|||
this.quiet = quiet |
|||
|
|||
// readyState
|
|||
this.building = false; |
|||
this.building = false |
|||
|
|||
this.socket = io(`https://io.now.sh?host=${host}`); |
|||
this.socket.once('error', this.onSocketError.bind(this)); |
|||
this.socket.on('state', this.onState.bind(this)); |
|||
this.socket.on('logs', this.onLog.bind(this)); |
|||
this.socket.on('backend', this.onComplete.bind(this)); |
|||
this.socket = io(`https://io.now.sh?host=${host}`) |
|||
this.socket.once('error', this.onSocketError.bind(this)) |
|||
this.socket.on('state', this.onState.bind(this)) |
|||
this.socket.on('logs', this.onLog.bind(this)) |
|||
this.socket.on('backend', this.onComplete.bind(this)) |
|||
|
|||
this.lines = new Lines(10); |
|||
this.lines = new Lines(10) |
|||
} |
|||
|
|||
onState (state) { |
|||
onState(state) { |
|||
if (!state.id) { |
|||
console.error('> Deployment not found'); |
|||
this.emit('error'); |
|||
return; |
|||
console.error('> Deployment not found') |
|||
this.emit('error') |
|||
return |
|||
} |
|||
|
|||
if (state.error) { |
|||
console.error('> Deployment error'); |
|||
this.emit('error'); |
|||
return; |
|||
console.error('> Deployment error') |
|||
this.emit('error') |
|||
return |
|||
} |
|||
|
|||
if (state.backend) { |
|||
this.onComplete(); |
|||
return; |
|||
this.onComplete() |
|||
return |
|||
} |
|||
|
|||
if (state.logs) { |
|||
state.logs.forEach(this.onLog, this); |
|||
state.logs.forEach(this.onLog, this) |
|||
} |
|||
} |
|||
|
|||
onLog (log) { |
|||
onLog(log) { |
|||
if (!this.building) { |
|||
if (!this.quiet) { |
|||
console.log('> Building'); |
|||
console.log('> Building') |
|||
} |
|||
this.building = true; |
|||
this.building = true |
|||
} |
|||
|
|||
if (this.quiet) return; |
|||
if (this.quiet) { |
|||
return |
|||
} |
|||
|
|||
if ('command' === log.type) { |
|||
console.log(`${chalk.gray('>')} ▲ ${log.data}`); |
|||
this.lines.reset(); |
|||
} else if ('stderr' === log.type) { |
|||
log.data.split('\n').forEach((v) => { |
|||
if (v.length) { |
|||
console.error(chalk.red(`> ${v}`)); |
|||
if (log.type === 'command') { |
|||
console.log(`${chalk.gray('>')} ▲ ${log.data}`) |
|||
this.lines.reset() |
|||
} else if (log.type === 'stderr') { |
|||
log.data.split('\n').forEach(v => { |
|||
if (v.length > 0) { |
|||
console.error(chalk.red(`> ${v}`)) |
|||
} |
|||
}); |
|||
this.lines.reset(); |
|||
} else if ('stdout' === log.type) { |
|||
log.data.split('\n').forEach((v) => { |
|||
if (v.length) { |
|||
this.lines.write(`${chalk.gray('>')} ${v}`); |
|||
}) |
|||
this.lines.reset() |
|||
} else if (log.type === 'stdout') { |
|||
log.data.split('\n').forEach(v => { |
|||
if (v.length > 0) { |
|||
this.lines.write(`${chalk.gray('>')} ${v}`) |
|||
} |
|||
}); |
|||
}) |
|||
} |
|||
} |
|||
|
|||
onComplete () { |
|||
this.socket.disconnect(); |
|||
onComplete() { |
|||
this.socket.disconnect() |
|||
|
|||
if (this.building) { |
|||
this.building = false; |
|||
this.building = false |
|||
} |
|||
|
|||
this.emit('close'); |
|||
this.emit('close') |
|||
} |
|||
|
|||
onSocketError (err) { |
|||
onSocketError(err) { |
|||
if (this.debug) { |
|||
console.log('> [debug] Socket error', err.stack); |
|||
console.log('> [debug] Socket error', err.stack) |
|||
} |
|||
} |
|||
|
|||
} |
|||
|
|||
class Lines { |
|||
|
|||
constructor (maxLines = 100) { |
|||
this.max = maxLines; |
|||
this.buf = []; |
|||
} |
|||
|
|||
write (str) { |
|||
const { max, buf } = this; |
|||
|
|||
if (buf.length === max) { |
|||
process.stdout.write(ansi.eraseLines(max + 1)); |
|||
buf.shift(); |
|||
buf.forEach((line) => console.log(line)); |
|||
} |
|||
|
|||
buf.push(str); |
|||
console.log(str); |
|||
} |
|||
|
|||
reset () { |
|||
this.buf = []; |
|||
} |
|||
|
|||
} |
|||
|
@ -1,82 +1,102 @@ |
|||
import Now from '../lib'; |
|||
// Ours
|
|||
import Now from '../lib' |
|||
|
|||
export default class Certs extends Now { |
|||
|
|||
ls () { |
|||
ls() { |
|||
return this.retry(async (bail, attempt) => { |
|||
if (this._debug) console.time(`> [debug] #${attempt} GET now/certs`); |
|||
const res = await this._fetch('/now/certs'); |
|||
if (this._debug) console.timeEnd(`> [debug] #${attempt} GET now/certs`); |
|||
const body = await res.json(); |
|||
return body.certs; |
|||
}); |
|||
if (this._debug) { |
|||
console.time(`> [debug] #${attempt} GET now/certs`) |
|||
} |
|||
|
|||
const res = await this._fetch('/now/certs') |
|||
|
|||
if (this._debug) { |
|||
console.timeEnd(`> [debug] #${attempt} GET now/certs`) |
|||
} |
|||
|
|||
const body = await res.json() |
|||
return body.certs |
|||
}) |
|||
} |
|||
|
|||
create (cn) { |
|||
return this.createCert(cn); |
|||
create(cn) { |
|||
return this.createCert(cn) |
|||
} |
|||
|
|||
renew (cn) { |
|||
return this.createCert(cn, { renew: true }); |
|||
renew(cn) { |
|||
return this.createCert(cn, {renew: true}) |
|||
} |
|||
|
|||
replace (cn, crt, key, ca) { |
|||
replace(cn, crt, key, ca) { |
|||
return this.retry(async (bail, attempt) => { |
|||
if (this._debug) console.time(`> [debug] #${attempt} PUT now/certs`); |
|||
if (this._debug) { |
|||
console.time(`> [debug] #${attempt} PUT now/certs`) |
|||
} |
|||
|
|||
const res = await this._fetch('/now/certs', { |
|||
method: 'PUT', |
|||
body: { |
|||
domains: [cn], |
|||
ca: ca, |
|||
ca, |
|||
cert: crt, |
|||
key: key |
|||
key |
|||
} |
|||
}); |
|||
if (this._debug) console.timeEnd(`> [debug] #${attempt} PUT now/certs`); |
|||
}) |
|||
|
|||
if (403 === res.status) { |
|||
return bail(new Error('Unauthorized')); |
|||
if (this._debug) { |
|||
console.timeEnd(`> [debug] #${attempt} PUT now/certs`) |
|||
} |
|||
|
|||
const body = await res.json(); |
|||
if (res.status === 403) { |
|||
return bail(new Error('Unauthorized')) |
|||
} |
|||
|
|||
const body = await res.json() |
|||
|
|||
if (res.status !== 200) { |
|||
if (404 === res.status || 400 === res.status) { |
|||
const err = new Error(body.error.message); |
|||
err.userError = true; |
|||
return bail(err); |
|||
} else { |
|||
throw new Error(body.error.message); |
|||
if (res.status === 404 || res.status === 400) { |
|||
const err = new Error(body.error.message) |
|||
err.userError = true |
|||
return bail(err) |
|||
} |
|||
|
|||
throw new Error(body.error.message) |
|||
} |
|||
|
|||
return body; |
|||
}); |
|||
return body |
|||
}) |
|||
} |
|||
|
|||
delete (cn) { |
|||
delete(cn) { |
|||
return this.retry(async (bail, attempt) => { |
|||
if (this._debug) console.time(`> [debug] #${attempt} DELETE now/certs/${cn}`); |
|||
const res = await this._fetch(`/now/certs/${cn}`, { method: 'DELETE' }); |
|||
if (this._debug) console.timeEnd(`> [debug] #${attempt} DELETE now/certs/${cn}`); |
|||
if (this._debug) { |
|||
console.time(`> [debug] #${attempt} DELETE now/certs/${cn}`) |
|||
} |
|||
|
|||
const res = await this._fetch(`/now/certs/${cn}`, {method: 'DELETE'}) |
|||
|
|||
if (403 === res.status) { |
|||
return bail(new Error('Unauthorized')); |
|||
if (this._debug) { |
|||
console.timeEnd(`> [debug] #${attempt} DELETE now/certs/${cn}`) |
|||
} |
|||
|
|||
const body = await res.json(); |
|||
if (res.status === 403) { |
|||
return bail(new Error('Unauthorized')) |
|||
} |
|||
|
|||
const body = await res.json() |
|||
|
|||
if (res.status !== 200) { |
|||
if (404 === res.status || 400 === res.status) { |
|||
const err = new Error(body.error.message); |
|||
err.userError = true; |
|||
return bail(err); |
|||
} else { |
|||
throw new Error(body.error.message); |
|||
if (res.status === 404 || res.status === 400) { |
|||
const err = new Error(body.error.message) |
|||
err.userError = true |
|||
return bail(err) |
|||
} |
|||
|
|||
throw new Error(body.error.message) |
|||
} |
|||
|
|||
return body; |
|||
}); |
|||
return body |
|||
}) |
|||
} |
|||
} |
|||
|
@ -1,81 +1,95 @@ |
|||
import ms from 'ms'; |
|||
import pkg from '../../package'; // relative to `build/` :\
|
|||
import fetch from 'node-fetch'; |
|||
import chalk from 'chalk'; |
|||
import compare from 'semver-compare'; |
|||
// Packages
|
|||
import ms from 'ms' |
|||
import fetch from 'node-fetch' |
|||
import chalk from 'chalk' |
|||
import compare from 'semver-compare' |
|||
|
|||
const isTTY = process.stdout.isTTY; |
|||
// Ours
|
|||
import pkg from '../../package' |
|||
|
|||
const isTTY = process.stdout.isTTY |
|||
|
|||
// if we're not in a tty the update checker
|
|||
// will always return a resolved promise
|
|||
const resolvedPromise = new Promise((resolve, reject) => resolve()); |
|||
const resolvedPromise = new Promise(resolve => resolve()) |
|||
|
|||
/** |
|||
* Configures auto updates. |
|||
* Sets up a `exit` listener to report them. |
|||
*/ |
|||
|
|||
export default function checkUpdate (opts = {}) { |
|||
export default function checkUpdate(opts = {}) { |
|||
if (!isTTY) { |
|||
// don't attempt to check for updates
|
|||
// if the user is piping or redirecting
|
|||
return resolvedPromise; |
|||
return resolvedPromise |
|||
} |
|||
|
|||
let updateData; |
|||
let updateData |
|||
|
|||
const update = check(opts).then((data) => { |
|||
updateData = data; |
|||
const update = check(opts).then(data => { |
|||
updateData = data |
|||
|
|||
// forces the `exit` event upon Ctrl + C
|
|||
process.on('SIGINT', () => { |
|||
// clean up output after ^C
|
|||
process.stdout.write('\n'); |
|||
process.exit(1); |
|||
}); |
|||
}, (err) => console.error(err.stack)); |
|||
process.stdout.write('\n') |
|||
process.exit(1) |
|||
}) |
|||
}, err => console.error(err.stack)) |
|||
|
|||
process.on('exit', (code) => { |
|||
process.on('exit', () => { |
|||
if (updateData) { |
|||
const { current, latest, at } = updateData; |
|||
const ago = ms(Date.now() - at); |
|||
const {current, latest, at} = updateData |
|||
const ago = ms(Date.now() - at) |
|||
console.log(`> ${chalk.white.bgRed('UPDATE NEEDED')} ` + |
|||
`Current: ${current} – ` + |
|||
`Latest ${chalk.bold(latest)} (released ${ago} ago)`); |
|||
console.log('> Run `npm install -g now` to update'); |
|||
`Latest ${chalk.bold(latest)} (released ${ago} ago)`) |
|||
console.log('> Run `npm install -g now` to update') |
|||
} |
|||
}); |
|||
}) |
|||
|
|||
return update; |
|||
return update |
|||
} |
|||
|
|||
function check ({ debug = false }) { |
|||
return new Promise((resolve, reject) => { |
|||
if (debug) console.log('> [debug] Checking for updates.'); |
|||
function check({debug = false}) { |
|||
return new Promise(resolve => { |
|||
if (debug) { |
|||
console.log('> [debug] Checking for updates.') |
|||
} |
|||
|
|||
fetch('https://registry.npmjs.org/now').then(res => { |
|||
if (res.status !== 200) { |
|||
if (debug) { |
|||
console.log(`> [debug] Update check error. NPM ${res.status}.`) |
|||
} |
|||
|
|||
fetch('https://registry.npmjs.org/now').then((res) => { |
|||
if (200 !== res.status) { |
|||
if (debug) console.log(`> [debug] Update check error. NPM ${res.status}.`); |
|||
resolve(false); |
|||
return; |
|||
resolve(false) |
|||
return |
|||
} |
|||
|
|||
res.json().then((data) => { |
|||
const { latest } = data['dist-tags']; |
|||
const current = pkg.version; |
|||
res.json().then(data => { |
|||
const {latest} = data['dist-tags'] |
|||
const current = pkg.version |
|||
|
|||
if (compare(latest, pkg.version) === 1) { |
|||
if (debug) { |
|||
console.log(`> [debug] Needs update. Current ${current}, latest ${latest}`) |
|||
} |
|||
|
|||
if (1 === compare(latest, pkg.version)) { |
|||
if (debug) console.log(`> [debug] Needs update. Current ${current}, latest ${latest}`); |
|||
resolve({ |
|||
latest, |
|||
current, |
|||
at: new Date(data.time[latest]) |
|||
}); |
|||
}) |
|||
} else { |
|||
if (debug) console.log(`> [debug] Up to date (${pkg.version}).`); |
|||
resolve(false); |
|||
if (debug) { |
|||
console.log(`> [debug] Up to date (${pkg.version}).`) |
|||
} |
|||
|
|||
resolve(false) |
|||
} |
|||
}, () => resolve(false)); |
|||
}, () => resolve(false)); |
|||
}); |
|||
}, () => resolve(false)) |
|||
}, () => resolve(false)) |
|||
}) |
|||
} |
|||
|
@ -1,10 +1,14 @@ |
|||
import { copy as _copy } from 'copy-paste'; |
|||
// Packages
|
|||
import {copy as _copy} from 'copy-paste' |
|||
|
|||
export default function copy (text) { |
|||
export default function copy(text) { |
|||
return new Promise((resolve, reject) => { |
|||
_copy(text, (err) => { |
|||
if (err) return reject(err); |
|||
resolve(); |
|||
}); |
|||
}); |
|||
_copy(text, err => { |
|||
if (err) { |
|||
return reject(err) |
|||
} |
|||
|
|||
resolve() |
|||
}) |
|||
}) |
|||
} |
|||
|
@ -1,10 +1,14 @@ |
|||
import dns from 'dns'; |
|||
// Packages
|
|||
import dns from 'dns' |
|||
|
|||
export function resolve4 (host) { |
|||
export default function resolve4(host) { |
|||
return new Promise((resolve, reject) => { |
|||
return dns.resolve4(host, (err, answer) => { |
|||
if (err) return reject(err); |
|||
resolve(answer); |
|||
}); |
|||
}); |
|||
if (err) { |
|||
return reject(err) |
|||
} |
|||
|
|||
resolve(answer) |
|||
}) |
|||
}) |
|||
} |
|||
|
@ -1,67 +1,86 @@ |
|||
import Now from '../lib'; |
|||
import isZeitWorld from './is-zeit-world'; |
|||
import chalk from 'chalk'; |
|||
import { DNS_VERIFICATION_ERROR } from './errors'; |
|||
// Packages
|
|||
import chalk from 'chalk' |
|||
|
|||
const domainRegex = /^((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}$/; |
|||
// Ours
|
|||
import Now from '../lib' |
|||
import isZeitWorld from './is-zeit-world' |
|||
import {DNS_VERIFICATION_ERROR} from './errors' |
|||
|
|||
const domainRegex = /^((?=[a-z0-9-]{1,63}\.)(xn--)?[a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,63}$/ |
|||
|
|||
export default class Domains extends Now { |
|||
|
|||
async ls () { |
|||
async ls() { |
|||
return this.retry(async (bail, attempt) => { |
|||
if (this._debug) console.time(`> [debug] #${attempt} GET /domains`); |
|||
const res = await this._fetch('/domains'); |
|||
if (this._debug) console.timeEnd(`> [debug] #${attempt} GET /domains`); |
|||
const body = await res.json(); |
|||
return body.domains; |
|||
}); |
|||
if (this._debug) { |
|||
console.time(`> [debug] #${attempt} GET /domains`) |
|||
} |
|||
|
|||
const res = await this._fetch('/domains') |
|||
|
|||
if (this._debug) { |
|||
console.timeEnd(`> [debug] #${attempt} GET /domains`) |
|||
} |
|||
|
|||
const body = await res.json() |
|||
return body.domains |
|||
}) |
|||
} |
|||
|
|||
async rm (name) { |
|||
async rm(name) { |
|||
return this.retry(async (bail, attempt) => { |
|||
if (this._debug) console.time(`> [debug] #${attempt} DELETE /domains/${name}`); |
|||
const res = await this._fetch(`/domains/${name}`, { method: 'DELETE' }); |
|||
if (this._debug) console.timeEnd(`> [debug] #${attempt} DELETE /domains/${name}`); |
|||
if (this._debug) { |
|||
console.time(`> [debug] #${attempt} DELETE /domains/${name}`) |
|||
} |
|||
|
|||
if (403 === res.status) { |
|||
return bail(new Error('Unauthorized')); |
|||
const res = await this._fetch(`/domains/${name}`, {method: 'DELETE'}) |
|||
|
|||
if (this._debug) { |
|||
console.timeEnd(`> [debug] #${attempt} DELETE /domains/${name}`) |
|||
} |
|||
|
|||
if (res.status === 403) { |
|||
return bail(new Error('Unauthorized')) |
|||
} |
|||
|
|||
if (res.status !== 200) { |
|||
const body = await res.json(); |
|||
throw new Error(body.error.message); |
|||
const body = await res.json() |
|||
throw new Error(body.error.message) |
|||
} |
|||
}); |
|||
}) |
|||
} |
|||
|
|||
async add (domain) { |
|||
async add(domain) { |
|||
if (!domainRegex.test(domain)) { |
|||
const err = new Error(`The supplied value ${chalk.bold(`"${domain}"`)} is not a valid domain.`); |
|||
err.userError = true; |
|||
throw err; |
|||
const err = new Error(`The supplied value ${chalk.bold(`"${domain}"`)} is not a valid domain.`) |
|||
err.userError = true |
|||
throw err |
|||
} |
|||
|
|||
let ns; |
|||
let ns |
|||
|
|||
try { |
|||
console.log('> Verifying nameservers…'); |
|||
const res = await this.getNameservers(domain); |
|||
ns = res.nameservers; |
|||
console.log('> Verifying nameservers…') |
|||
const res = await this.getNameservers(domain) |
|||
ns = res.nameservers |
|||
} catch (err) { |
|||
const err2 = new Error(`Unable to fetch nameservers for ${chalk.underline(chalk.bold(domain))}.`); |
|||
err2.userError = true; |
|||
throw err2; |
|||
const err2 = new Error(`Unable to fetch nameservers for ${chalk.underline(chalk.bold(domain))}.`) |
|||
err2.userError = true |
|||
throw err2 |
|||
} |
|||
|
|||
if (isZeitWorld(ns)) { |
|||
console.log(`> Verification ${chalk.bold('OK')}!`); |
|||
return this.setupDomain(domain); |
|||
} else { |
|||
if (this._debug) console.log(`> [debug] Supplied domain "${domain}" has non-zeit nameservers`); |
|||
const err3 = new Error(DNS_VERIFICATION_ERROR); |
|||
err3.userError = true; |
|||
throw err3; |
|||
console.log(`> Verification ${chalk.bold('OK')}!`) |
|||
return this.setupDomain(domain) |
|||
} |
|||
|
|||
if (this._debug) { |
|||
console.log(`> [debug] Supplied domain "${domain}" has non-zeit nameservers`) |
|||
} |
|||
|
|||
const err3 = new Error(DNS_VERIFICATION_ERROR) |
|||
err3.userError = true |
|||
throw err3 |
|||
} |
|||
|
|||
} |
|||
|
@ -1,26 +1,27 @@ |
|||
import ms from 'ms'; |
|||
import chalk from 'chalk'; |
|||
// Packages
|
|||
import ms from 'ms' |
|||
import chalk from 'chalk' |
|||
|
|||
export function handleError (err) { |
|||
if (403 === err.status) { |
|||
error('Authentication error. Run `now -L` or `now --login` to log-in again.'); |
|||
} else if (429 === err.status) { |
|||
if (null != err.retryAfter) { |
|||
error('Rate limit exceeded error. Try again in ' + |
|||
ms(err.retryAfter * 1000, { long: true }) + |
|||
', or upgrade your account: https://zeit.co/now#pricing'); |
|||
export function handleError(err) { |
|||
if (err.status === 403) { |
|||
error('Authentication error. Run `now -L` or `now --login` to log-in again.') |
|||
} else if (err.status === 429) { |
|||
if (err.retryAfter === null) { |
|||
error('Rate limit exceeded error. Please try later.') |
|||
} else { |
|||
error('Rate limit exceeded error. Please try later.'); |
|||
error('Rate limit exceeded error. Try again in ' + |
|||
ms(err.retryAfter * 1000, {long: true}) + |
|||
', or upgrade your account: https://zeit.co/now#pricing') |
|||
} |
|||
} else if (err.userError) { |
|||
error(err.message); |
|||
} else if (500 === err.status) { |
|||
error('Unexpected server error. Please retry.'); |
|||
error(err.message) |
|||
} else if (err.status === 500) { |
|||
error('Unexpected server error. Please retry.') |
|||
} else { |
|||
error(`Unexpected error. Please try later. (${err.message})`); |
|||
error(`Unexpected error. Please try later. (${err.message})`) |
|||
} |
|||
} |
|||
|
|||
export function error (err) { |
|||
console.error(`> ${chalk.red('Error!')} ${err}`); |
|||
export function error(err) { |
|||
console.error(`> ${chalk.red('Error!')} ${err}`) |
|||
} |
|||
|
@ -1,11 +1,12 @@ |
|||
import chalk from 'chalk'; |
|||
// Packages
|
|||
import chalk from 'chalk' |
|||
|
|||
export const DNS_VERIFICATION_ERROR = `Please make sure that your nameservers point to ${chalk.underline('zeit.world')}.
|
|||
> Examples: (full list at ${chalk.underline('https://zeit.world')}) |
|||
> ${chalk.gray('-')} ${chalk.underline('california.zeit.world')} ${chalk.dim('173.255.215.107')} |
|||
> ${chalk.gray('-')} ${chalk.underline('newark.zeit.world')} ${chalk.dim('173.255.231.87')} |
|||
> ${chalk.gray('-')} ${chalk.underline('london.zeit.world')} ${chalk.dim('178.62.47.76')} |
|||
> ${chalk.gray('-')} ${chalk.underline('singapore.zeit.world')} ${chalk.dim('119.81.97.170')}`;
|
|||
> ${chalk.gray('-')} ${chalk.underline('singapore.zeit.world')} ${chalk.dim('119.81.97.170')}` |
|||
|
|||
export const DOMAIN_VERIFICATION_ERROR = DNS_VERIFICATION_ERROR + |
|||
`\n> Alternatively, ensure it resolves to ${chalk.underline('alias.zeit.co')} via ${chalk.dim('CNAME')} / ${chalk.dim('ALIAS')}.`; |
|||
`\n> Alternatively, ensure it resolves to ${chalk.underline('alias.zeit.co')} via ${chalk.dim('CNAME')} / ${chalk.dim('ALIAS')}.` |
|||
|
File diff suppressed because it is too large
@ -1,98 +1,115 @@ |
|||
import Now from '../lib'; |
|||
// Ours
|
|||
import Now from '../lib' |
|||
|
|||
export default class Secrets extends Now { |
|||
|
|||
ls () { |
|||
return this.listSecrets(); |
|||
ls() { |
|||
return this.listSecrets() |
|||
} |
|||
|
|||
rm (nameOrId) { |
|||
rm(nameOrId) { |
|||
return this.retry(async (bail, attempt) => { |
|||
if (this._debug) console.time(`> [debug] #${attempt} DELETE /secrets/${nameOrId}`); |
|||
const res = await this._fetch(`/now/secrets/${nameOrId}`, { method: 'DELETE' }); |
|||
if (this._debug) console.timeEnd(`> [debug] #${attempt} DELETE /secrets/${nameOrId}`); |
|||
if (this._debug) { |
|||
console.time(`> [debug] #${attempt} DELETE /secrets/${nameOrId}`) |
|||
} |
|||
|
|||
const res = await this._fetch(`/now/secrets/${nameOrId}`, {method: 'DELETE'}) |
|||
|
|||
if (this._debug) { |
|||
console.timeEnd(`> [debug] #${attempt} DELETE /secrets/${nameOrId}`) |
|||
} |
|||
|
|||
if (403 === res.status) { |
|||
return bail(new Error('Unauthorized')); |
|||
if (res.status === 403) { |
|||
return bail(new Error('Unauthorized')) |
|||
} |
|||
|
|||
const body = await res.json(); |
|||
const body = await res.json() |
|||
|
|||
if (res.status !== 200) { |
|||
if (404 === res.status || 400 === res.status) { |
|||
const err = new Error(body.error.message); |
|||
err.userError = true; |
|||
return bail(err); |
|||
} else { |
|||
throw new Error(body.error.message); |
|||
if (res.status === 404 || res.status === 400) { |
|||
const err = new Error(body.error.message) |
|||
err.userError = true |
|||
return bail(err) |
|||
} |
|||
|
|||
throw new Error(body.error.message) |
|||
} |
|||
|
|||
return body; |
|||
}); |
|||
return body |
|||
}) |
|||
} |
|||
|
|||
add (name, value) { |
|||
add(name, value) { |
|||
return this.retry(async (bail, attempt) => { |
|||
if (this._debug) console.time(`> [debug] #${attempt} POST /secrets`); |
|||
if (this._debug) { |
|||
console.time(`> [debug] #${attempt} POST /secrets`) |
|||
} |
|||
|
|||
const res = await this._fetch('/now/secrets', { |
|||
method: 'POST', |
|||
body: { |
|||
name, |
|||
value: value.toString() |
|||
} |
|||
}); |
|||
if (this._debug) console.timeEnd(`> [debug] #${attempt} POST /secrets`); |
|||
}) |
|||
|
|||
if (403 === res.status) { |
|||
return bail(new Error('Unauthorized')); |
|||
if (this._debug) { |
|||
console.timeEnd(`> [debug] #${attempt} POST /secrets`) |
|||
} |
|||
|
|||
const body = await res.json(); |
|||
if (res.status === 403) { |
|||
return bail(new Error('Unauthorized')) |
|||
} |
|||
|
|||
const body = await res.json() |
|||
|
|||
if (res.status !== 200) { |
|||
if (404 === res.status || 400 === res.status) { |
|||
const err = new Error(body.error.message); |
|||
err.userError = true; |
|||
return bail(err); |
|||
} else { |
|||
throw new Error(body.error.message); |
|||
if (res.status === 404 || res.status === 400) { |
|||
const err = new Error(body.error.message) |
|||
err.userError = true |
|||
return bail(err) |
|||
} |
|||
|
|||
throw new Error(body.error.message) |
|||
} |
|||
|
|||
return body; |
|||
}); |
|||
return body |
|||
}) |
|||
} |
|||
|
|||
rename (nameOrId, newName) { |
|||
rename(nameOrId, newName) { |
|||
return this.retry(async (bail, attempt) => { |
|||
if (this._debug) console.time(`> [debug] #${attempt} PATCH /secrets/${nameOrId}`); |
|||
if (this._debug) { |
|||
console.time(`> [debug] #${attempt} PATCH /secrets/${nameOrId}`) |
|||
} |
|||
|
|||
const res = await this._fetch(`/now/secrets/${nameOrId}`, { |
|||
method: 'PATCH', |
|||
body: { |
|||
name: newName |
|||
} |
|||
}); |
|||
if (this._debug) console.timeEnd(`> [debug] #${attempt} PATCH /secrets/${nameOrId}`); |
|||
}) |
|||
|
|||
if (403 === res.status) { |
|||
return bail(new Error('Unauthorized')); |
|||
if (this._debug) { |
|||
console.timeEnd(`> [debug] #${attempt} PATCH /secrets/${nameOrId}`) |
|||
} |
|||
|
|||
const body = await res.json(); |
|||
if (res.status === 403) { |
|||
return bail(new Error('Unauthorized')) |
|||
} |
|||
|
|||
const body = await res.json() |
|||
|
|||
if (res.status !== 200) { |
|||
if (404 === res.status || 400 === res.status) { |
|||
const err = new Error(body.error.message); |
|||
err.userError = true; |
|||
return bail(err); |
|||
} else { |
|||
throw new Error(body.error.message); |
|||
if (res.status === 404 || res.status === 400) { |
|||
const err = new Error(body.error.message) |
|||
err.userError = true |
|||
return bail(err) |
|||
} |
|||
|
|||
throw new Error(body.error.message) |
|||
} |
|||
|
|||
return body; |
|||
}); |
|||
return body |
|||
}) |
|||
} |
|||
|
|||
} |
|||
|
@ -1,3 +1,3 @@ |
|||
export default function strlen (str) { |
|||
return str.replace(/\x1b[^m]*m/g, '').length; |
|||
export default function strlen(str) { |
|||
return str.replace(/\x1b[^m]*m/g, '').length |
|||
} |
|||
|
@ -1,20 +1,22 @@ |
|||
import getFiles from './get-files'; |
|||
import { resolve } from 'path'; |
|||
// Native
|
|||
import {resolve} from 'path' |
|||
|
|||
// Ours
|
|||
import {npm as getFiles} from './get-files' |
|||
|
|||
getFiles(resolve('../mng-test/files-in-package')) |
|||
.then(files => { |
|||
console.log(files); |
|||
console.log(files) |
|||
|
|||
getFiles(resolve('../mng-test/files-in-package-ignore')) |
|||
.then(files2 => { |
|||
console.log('ignored: '); |
|||
console.log(files2); |
|||
console.log('ignored: ') |
|||
console.log(files2) |
|||
}) |
|||
.catch(err => { |
|||
console.log(err.stack); |
|||
}); |
|||
console.log(err.stack) |
|||
}) |
|||
}) |
|||
.catch(err => { |
|||
console.log(err.stack); |
|||
}); |
|||
|
|||
console.log(err.stack) |
|||
}) |
|||
|
@ -1,4 +1,7 @@ |
|||
import os from 'os'; |
|||
import { version } from '../../package'; |
|||
// Native
|
|||
import os from 'os' |
|||
|
|||
export default `now ${version} node-${process.version} ${os.platform()} (${os.arch()})`; |
|||
// Ours
|
|||
import {version} from '../../package' |
|||
|
|||
export default `now ${version} node-${process.version} ${os.platform()} (${os.arch()})` |
|||
|
@ -1,30 +1,34 @@ |
|||
import chalk from 'chalk'; |
|||
import chalk from 'chalk' |
|||
|
|||
export default function (opts) { |
|||
return new Promise((resolve, reject) => { |
|||
opts.forEach(([, text], i) => { |
|||
console.log(`${chalk.gray('>')} [${chalk.bold(i + 1)}] ${text}`); |
|||
}); |
|||
const ondata = (v) => { |
|||
const s = v.toString(); |
|||
if ('\u0003' === s) { |
|||
cleanup(); |
|||
reject(new Error('Aborted')); |
|||
return; |
|||
console.log(`${chalk.gray('>')} [${chalk.bold(i + 1)}] ${text}`) |
|||
}) |
|||
|
|||
const ondata = v => { |
|||
const s = v.toString() |
|||
|
|||
const cleanup = () => { |
|||
process.stdin.setRawMode(false) |
|||
process.stdin.removeListener('data', ondata) |
|||
} |
|||
|
|||
const n = Number(s); |
|||
if (s === '\u0003') { |
|||
cleanup() |
|||
reject(new Error('Aborted')) |
|||
return |
|||
} |
|||
|
|||
const n = Number(s) |
|||
if (opts[n - 1]) { |
|||
cleanup(); |
|||
resolve(opts[n - 1][0]); |
|||
cleanup() |
|||
resolve(opts[n - 1][0]) |
|||
} |
|||
}; |
|||
const cleanup = () => { |
|||
process.stdin.setRawMode(false); |
|||
process.stdin.removeListener('data', ondata); |
|||
}; |
|||
process.stdin.setRawMode(true); |
|||
process.stdin.resume(); |
|||
process.stdin.on('data', ondata); |
|||
}); |
|||
} |
|||
|
|||
process.stdin.setRawMode(true) |
|||
process.stdin.resume() |
|||
process.stdin.on('data', ondata) |
|||
}) |
|||
} |
|||
|
@ -1,130 +1,132 @@ |
|||
import test from 'ava'; |
|||
import { join, resolve } from 'path'; |
|||
import { |
|||
npm as getNpmFiles_, |
|||
docker as getDockerFiles |
|||
} from '../lib/get-files'; |
|||
import hash from '../lib/hash'; |
|||
import { asc as alpha } from 'alpha-sort'; |
|||
import { readFile } from 'fs-promise'; |
|||
|
|||
const prefix = join(__dirname, '_fixtures') + '/'; |
|||
const base = (path) => path.replace(prefix, ''); |
|||
const fixture = (name) => resolve(`./_fixtures/${name}`); |
|||
// Native
|
|||
import {join, resolve} from 'path' |
|||
|
|||
// overload to force debugging
|
|||
const getNpmFiles = async (dir) => { |
|||
const pkg = await readJSON(resolve(dir, 'package.json')); |
|||
return getNpmFiles_(dir, pkg); |
|||
}; |
|||
// Packages
|
|||
import test from 'ava' |
|||
import {asc as alpha} from 'alpha-sort' |
|||
import {readFile} from 'fs-promise' |
|||
|
|||
// Ours
|
|||
import {npm as getNpmFiles_, docker as getDockerFiles} from '../lib/get-files' |
|||
import hash from '../lib/hash' |
|||
|
|||
const prefix = join(__dirname, '_fixtures') + '/' |
|||
const base = path => path.replace(prefix, '') |
|||
const fixture = name => resolve(`./_fixtures/${name}`) |
|||
|
|||
const readJSON = async (file) => { |
|||
const data = await readFile(file); |
|||
return JSON.parse(data); |
|||
}; |
|||
const readJSON = async file => { |
|||
const data = await readFile(file) |
|||
return JSON.parse(data) |
|||
} |
|||
|
|||
// overload to force debugging
|
|||
const getNpmFiles = async dir => { |
|||
const pkg = await readJSON(resolve(dir, 'package.json')) |
|||
return getNpmFiles_(dir, pkg) |
|||
} |
|||
|
|||
test('`files`', async t => { |
|||
let files = await getNpmFiles(fixture('files-in-package')); |
|||
t.is(files.length, 3); |
|||
files = files.sort(alpha); |
|||
t.is(base(files[0]), 'files-in-package/build/a/b/c/d.js'); |
|||
t.is(base(files[1]), 'files-in-package/build/a/e.js'); |
|||
t.is(base(files[2]), 'files-in-package/package.json'); |
|||
}); |
|||
let files = await getNpmFiles(fixture('files-in-package')) |
|||
t.is(files.length, 3) |
|||
files = files.sort(alpha) |
|||
t.is(base(files[0]), 'files-in-package/build/a/b/c/d.js') |
|||
t.is(base(files[1]), 'files-in-package/build/a/e.js') |
|||
t.is(base(files[2]), 'files-in-package/package.json') |
|||
}) |
|||
|
|||
test('`files` + `.*.swp` + `.npmignore`', async t => { |
|||
let files = await getNpmFiles(fixture('files-in-package-ignore')); |
|||
files = files.sort(alpha); |
|||
t.is(files.length, 3); |
|||
t.is(base(files[0]), 'files-in-package-ignore/build/a/b/c/d.js'); |
|||
t.is(base(files[1]), 'files-in-package-ignore/build/a/e.js'); |
|||
t.is(base(files[2]), 'files-in-package-ignore/package.json'); |
|||
}); |
|||
let files = await getNpmFiles(fixture('files-in-package-ignore')) |
|||
files = files.sort(alpha) |
|||
t.is(files.length, 3) |
|||
t.is(base(files[0]), 'files-in-package-ignore/build/a/b/c/d.js') |
|||
t.is(base(files[1]), 'files-in-package-ignore/build/a/e.js') |
|||
t.is(base(files[2]), 'files-in-package-ignore/package.json') |
|||
}) |
|||
|
|||
test('simple', async t => { |
|||
let files = await getNpmFiles(fixture('simple')); |
|||
files = files.sort(alpha); |
|||
t.is(files.length, 5); |
|||
t.is(base(files[0]), 'simple/bin/test'); |
|||
t.is(base(files[1]), 'simple/index.js'); |
|||
t.is(base(files[2]), 'simple/lib/woot'); |
|||
t.is(base(files[3]), 'simple/lib/woot.jsx'); |
|||
t.is(base(files[4]), 'simple/package.json'); |
|||
}); |
|||
let files = await getNpmFiles(fixture('simple')) |
|||
files = files.sort(alpha) |
|||
t.is(files.length, 5) |
|||
t.is(base(files[0]), 'simple/bin/test') |
|||
t.is(base(files[1]), 'simple/index.js') |
|||
t.is(base(files[2]), 'simple/lib/woot') |
|||
t.is(base(files[3]), 'simple/lib/woot.jsx') |
|||
t.is(base(files[4]), 'simple/package.json') |
|||
}) |
|||
|
|||
test('simple with main', async t => { |
|||
let files = await getNpmFiles(fixture('simple-main')); |
|||
t.is(files.length, 3); |
|||
files = files.sort(alpha); |
|||
t.is(files.length, 3); |
|||
t.is(base(files[0]), 'simple-main/build/a.js'); |
|||
t.is(base(files[1]), 'simple-main/index.js'); |
|||
t.is(base(files[2]), 'simple-main/package.json'); |
|||
}); |
|||
let files = await getNpmFiles(fixture('simple-main')) |
|||
t.is(files.length, 3) |
|||
files = files.sort(alpha) |
|||
t.is(files.length, 3) |
|||
t.is(base(files[0]), 'simple-main/build/a.js') |
|||
t.is(base(files[1]), 'simple-main/index.js') |
|||
t.is(base(files[2]), 'simple-main/package.json') |
|||
}) |
|||
|
|||
test('hashes', async t => { |
|||
const files = await getNpmFiles(fixture('hashes')); |
|||
const hashes = await hash(files); |
|||
t.is(hashes.size, 3); |
|||
t.is(hashes.get('277c55a2042910b9fe706ad00859e008c1b7d172').names[0], prefix + 'hashes/dei.png'); |
|||
t.is(hashes.get('277c55a2042910b9fe706ad00859e008c1b7d172').names[1], prefix + 'hashes/duplicate/dei.png'); |
|||
t.is(hashes.get('56c00d0466fc6bdd41b13dac5fc920cc30a63b45').names[0], prefix + 'hashes/index.js'); |
|||
t.is(hashes.get('706214f42ae940a01d2aa60c5e32408f4d2127dd').names[0], prefix + 'hashes/package.json'); |
|||
}); |
|||
const files = await getNpmFiles(fixture('hashes')) |
|||
const hashes = await hash(files) |
|||
t.is(hashes.size, 3) |
|||
t.is(hashes.get('277c55a2042910b9fe706ad00859e008c1b7d172').names[0], prefix + 'hashes/dei.png') |
|||
t.is(hashes.get('277c55a2042910b9fe706ad00859e008c1b7d172').names[1], prefix + 'hashes/duplicate/dei.png') |
|||
t.is(hashes.get('56c00d0466fc6bdd41b13dac5fc920cc30a63b45').names[0], prefix + 'hashes/index.js') |
|||
t.is(hashes.get('706214f42ae940a01d2aa60c5e32408f4d2127dd').names[0], prefix + 'hashes/package.json') |
|||
}) |
|||
|
|||
test('ignore node_modules', async t => { |
|||
let files = await getNpmFiles(fixture('no-node_modules')); |
|||
files = files.sort(alpha); |
|||
t.is(files.length, 2); |
|||
t.is(base(files[0]), 'no-node_modules/index.js'); |
|||
t.is(base(files[1]), 'no-node_modules/package.json'); |
|||
}); |
|||
let files = await getNpmFiles(fixture('no-node_modules')) |
|||
files = files.sort(alpha) |
|||
t.is(files.length, 2) |
|||
t.is(base(files[0]), 'no-node_modules/index.js') |
|||
t.is(base(files[1]), 'no-node_modules/package.json') |
|||
}) |
|||
|
|||
test('ignore nested `node_modules` with .npmignore **', async t => { |
|||
let files = await getNpmFiles(fixture('nested-node_modules')); |
|||
files = files.sort(alpha); |
|||
t.is(files.length, 2); |
|||
t.is(base(files[0]), 'nested-node_modules/index.js'); |
|||
t.is(base(files[1]), 'nested-node_modules/package.json'); |
|||
}); |
|||
let files = await getNpmFiles(fixture('nested-node_modules')) |
|||
files = files.sort(alpha) |
|||
t.is(files.length, 2) |
|||
t.is(base(files[0]), 'nested-node_modules/index.js') |
|||
t.is(base(files[1]), 'nested-node_modules/package.json') |
|||
}) |
|||
|
|||
test('include `main` even if not in files', async t => { |
|||
let files = await getNpmFiles(fixture('always-include-main')); |
|||
files = files.sort(alpha); |
|||
t.is(files.length, 3); |
|||
t.is(base(files[0]), 'always-include-main/a.js'); |
|||
t.is(base(files[1]), 'always-include-main/package.json'); |
|||
t.is(base(files[2]), 'always-include-main/woot.js'); |
|||
}); |
|||
let files = await getNpmFiles(fixture('always-include-main')) |
|||
files = files.sort(alpha) |
|||
t.is(files.length, 3) |
|||
t.is(base(files[0]), 'always-include-main/a.js') |
|||
t.is(base(files[1]), 'always-include-main/package.json') |
|||
t.is(base(files[2]), 'always-include-main/woot.js') |
|||
}) |
|||
|
|||
test('support whitelisting with .npmignore and !', async t => { |
|||
let files = await getNpmFiles(fixture('negation')); |
|||
files = files.sort(alpha); |
|||
t.is(files.length, 2); |
|||
t.is(base(files[0]), 'negation/a.js'); |
|||
t.is(base(files[1]), 'negation/package.json'); |
|||
}); |
|||
let files = await getNpmFiles(fixture('negation')) |
|||
files = files.sort(alpha) |
|||
t.is(files.length, 2) |
|||
t.is(base(files[0]), 'negation/a.js') |
|||
t.is(base(files[1]), 'negation/package.json') |
|||
}) |
|||
|
|||
test('support `now.files`', async t => { |
|||
let files = await getNpmFiles(fixture('now-files')); |
|||
files = files.sort(alpha); |
|||
t.is(files.length, 2); |
|||
t.is(base(files[0]), 'now-files/b.js'); |
|||
t.is(base(files[1]), 'now-files/package.json'); |
|||
}); |
|||
let files = await getNpmFiles(fixture('now-files')) |
|||
files = files.sort(alpha) |
|||
t.is(files.length, 2) |
|||
t.is(base(files[0]), 'now-files/b.js') |
|||
t.is(base(files[1]), 'now-files/package.json') |
|||
}) |
|||
|
|||
test('support docker', async t => { |
|||
let files = await getDockerFiles(fixture('dockerfile')); |
|||
files = files.sort(alpha); |
|||
t.is(files.length, 2); |
|||
t.is(base(files[0]), 'dockerfile/Dockerfile'); |
|||
t.is(base(files[1]), 'dockerfile/a.js'); |
|||
}); |
|||
let files = await getDockerFiles(fixture('dockerfile')) |
|||
files = files.sort(alpha) |
|||
t.is(files.length, 2) |
|||
t.is(base(files[0]), 'dockerfile/Dockerfile') |
|||
t.is(base(files[1]), 'dockerfile/a.js') |
|||
}) |
|||
|
|||
test('prefix regression', async t => { |
|||
let files = await getNpmFiles(fixture('prefix-regression')); |
|||
files = files.sort(alpha); |
|||
t.is(files.length, 2); |
|||
t.is(base(files[0]), 'prefix-regression/package.json'); |
|||
t.is(base(files[1]), 'prefix-regression/woot.js'); |
|||
}); |
|||
let files = await getNpmFiles(fixture('prefix-regression')) |
|||
files = files.sort(alpha) |
|||
t.is(files.length, 2) |
|||
t.is(base(files[0]), 'prefix-regression/package.json') |
|||
t.is(base(files[1]), 'prefix-regression/woot.js') |
|||
}) |
|||
|
@ -1,26 +1,26 @@ |
|||
import test from 'ava'; |
|||
import toHost from '../lib/to-host'; |
|||
import test from 'ava' |
|||
import toHost from '../lib/to-host' |
|||
|
|||
test('simple', async t => { |
|||
t.is(toHost('zeit.co'), 'zeit.co'); |
|||
}); |
|||
t.is(toHost('zeit.co'), 'zeit.co') |
|||
}) |
|||
|
|||
test('leading //', async t => { |
|||
t.is(toHost('//zeit-logos-rnemgaicnc.now.sh'), 'zeit-logos-rnemgaicnc.now.sh'); |
|||
}); |
|||
t.is(toHost('//zeit-logos-rnemgaicnc.now.sh'), 'zeit-logos-rnemgaicnc.now.sh') |
|||
}) |
|||
|
|||
test('leading http://', async t => { |
|||
t.is(toHost('http://zeit-logos-rnemgaicnc.now.sh'), 'zeit-logos-rnemgaicnc.now.sh'); |
|||
}); |
|||
t.is(toHost('http://zeit-logos-rnemgaicnc.now.sh'), 'zeit-logos-rnemgaicnc.now.sh') |
|||
}) |
|||
|
|||
test('leading https://', async t => { |
|||
t.is(toHost('https://zeit-logos-rnemgaicnc.now.sh'), 'zeit-logos-rnemgaicnc.now.sh'); |
|||
}); |
|||
t.is(toHost('https://zeit-logos-rnemgaicnc.now.sh'), 'zeit-logos-rnemgaicnc.now.sh') |
|||
}) |
|||
|
|||
test('leading https:// and path', async t => { |
|||
t.is(toHost('https://zeit-logos-rnemgaicnc.now.sh/path'), 'zeit-logos-rnemgaicnc.now.sh'); |
|||
}); |
|||
t.is(toHost('https://zeit-logos-rnemgaicnc.now.sh/path'), 'zeit-logos-rnemgaicnc.now.sh') |
|||
}) |
|||
|
|||
test('simple and path', async t => { |
|||
t.is(toHost('zeit.co/test'), 'zeit.co'); |
|||
}); |
|||
t.is(toHost('zeit.co/test'), 'zeit.co') |
|||
}) |
|||
|
Loading…
Reference in new issue