mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-11 12:57:46 +00:00
Compare commits
30 Commits
@vercel/py
...
@vercel/bu
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2b62de803f | ||
|
|
196433ec9d | ||
|
|
0cdd571087 | ||
|
|
5e2227507d | ||
|
|
e3d478a471 | ||
|
|
187d41434a | ||
|
|
f6fde2d351 | ||
|
|
e09ceca95d | ||
|
|
d9318af654 | ||
|
|
679cd6f14e | ||
|
|
47c7a13324 | ||
|
|
f498d25d8b | ||
|
|
726d3924ae | ||
|
|
d3e6c2d335 | ||
|
|
f9ed84a5c9 | ||
|
|
88a815b5f0 | ||
|
|
9f49743ea4 | ||
|
|
0ac3ae19c0 | ||
|
|
e7920fd783 | ||
|
|
b4c13470df | ||
|
|
2a797b77b9 | ||
|
|
85a34126df | ||
|
|
92889c5376 | ||
|
|
66a7fa30b8 | ||
|
|
a7ba405503 | ||
|
|
84145245ba | ||
|
|
90d2e8b63b | ||
|
|
0d31fe8018 | ||
|
|
37d747c241 | ||
|
|
3f052d905f |
4
.github/ISSUE_TEMPLATE/config.yml
vendored
4
.github/ISSUE_TEMPLATE/config.yml
vendored
@@ -4,8 +4,8 @@ contact_links:
|
||||
url: https://vercel.com/support/request
|
||||
about: Report a bug using the Vercel support form
|
||||
- name: Feature Request
|
||||
url: https://github.com/vercel/vercel/discussions/new?category_id=66161
|
||||
url: https://github.com/vercel/vercel/discussions/new?category=ideas
|
||||
about: Share ideas for new features
|
||||
- name: Ask a Question
|
||||
url: https://github.com/vercel/vercel/discussions/new?category_id=66160
|
||||
url: https://github.com/vercel/vercel/discussions/new?category=help
|
||||
about: Ask the community for help
|
||||
|
||||
2
.github/workflows/test-integration-dev.yml
vendored
2
.github/workflows/test-integration-dev.yml
vendored
@@ -11,7 +11,7 @@ on:
|
||||
jobs:
|
||||
test:
|
||||
name: Dev
|
||||
timeout-minutes: 45
|
||||
timeout-minutes: 60
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
|
||||
30
packages/now-build-utils/build.js
Normal file
30
packages/now-build-utils/build.js
Normal file
@@ -0,0 +1,30 @@
|
||||
#!/usr/bin/env node
|
||||
const fs = require('fs-extra');
|
||||
const execa = require('execa');
|
||||
const { join } = require('path');
|
||||
|
||||
async function main() {
|
||||
const outDir = join(__dirname, 'dist');
|
||||
|
||||
// Start fresh
|
||||
await fs.remove(outDir);
|
||||
|
||||
// Compile TypeScript
|
||||
await execa('tsc', [], { stdio: 'inherit' });
|
||||
|
||||
// Run `ncc`
|
||||
const mainDir = join(outDir, 'main');
|
||||
await execa('ncc', ['build', 'src/index.ts', '-o', mainDir], {
|
||||
stdio: 'inherit',
|
||||
});
|
||||
// Move compiled ncc file to out dir
|
||||
await fs.rename(join(mainDir, 'index.js'), join(outDir, 'index.js'));
|
||||
|
||||
// Delete leftover "main" dir
|
||||
await fs.remove(mainDir);
|
||||
}
|
||||
|
||||
main().catch(err => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -1,13 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
out="dist"
|
||||
|
||||
rm -rf "$out"
|
||||
|
||||
tsc
|
||||
|
||||
rm "$out/index.js"
|
||||
ncc build "src/index.ts" -o "$out/main"
|
||||
mv "$out/main/index.js" "$out/index.js"
|
||||
rm -rf "$out/main"
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/build-utils",
|
||||
"version": "2.7.0",
|
||||
"version": "2.9.0",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.js",
|
||||
@@ -11,10 +11,10 @@
|
||||
"directory": "packages/now-build-utils"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "./build.sh",
|
||||
"build": "node build",
|
||||
"test-unit": "jest --env node --verbose --runInBand --bail test/unit.*test.*",
|
||||
"test-integration-once": "jest --env node --verbose --runInBand --bail test/integration.test.js",
|
||||
"prepublishOnly": "./build.sh"
|
||||
"prepublishOnly": "node build"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@iarna/toml": "2.2.3",
|
||||
|
||||
@@ -4,28 +4,34 @@ import { NodeVersion } from '../types';
|
||||
import { NowBuildError } from '../errors';
|
||||
import debug from '../debug';
|
||||
|
||||
const allOptions: NodeVersion[] = [
|
||||
const allOptions = [
|
||||
{ major: 14, range: '14.x', runtime: 'nodejs14.x' },
|
||||
{ major: 12, range: '12.x', runtime: 'nodejs12.x' },
|
||||
{ major: 10, range: '10.x', runtime: 'nodejs10.x' },
|
||||
{
|
||||
major: 10,
|
||||
range: '10.x',
|
||||
runtime: 'nodejs10.x',
|
||||
discontinueDate: new Date('2021-03-30'),
|
||||
},
|
||||
{
|
||||
major: 8,
|
||||
range: '8.10.x',
|
||||
runtime: 'nodejs8.10',
|
||||
discontinueDate: new Date('2020-01-06'),
|
||||
},
|
||||
];
|
||||
] as const;
|
||||
|
||||
const pleaseSet =
|
||||
'Please set "engines": { "node": "' +
|
||||
'Please change your Project Settings or set "engines": { "node": "' +
|
||||
getLatestNodeVersion().range +
|
||||
'" } in your `package.json` file to upgrade to Node.js ' +
|
||||
'" } in your `package.json` file to use Node.js ' +
|
||||
getLatestNodeVersion().major +
|
||||
'.';
|
||||
const upstreamProvider =
|
||||
'This change is the result of a decision made by an upstream infrastructure provider (AWS).' +
|
||||
'\nRead more: https://docs.aws.amazon.com/lambda/latest/dg/runtime-support-policy.html';
|
||||
|
||||
export function getLatestNodeVersion(): NodeVersion {
|
||||
export function getLatestNodeVersion() {
|
||||
return allOptions[0];
|
||||
}
|
||||
|
||||
@@ -37,7 +43,7 @@ export async function getSupportedNodeVersion(
|
||||
engineRange?: string,
|
||||
isAuto?: boolean
|
||||
): Promise<NodeVersion> {
|
||||
let selection = getLatestNodeVersion();
|
||||
let selection: NodeVersion = getLatestNodeVersion();
|
||||
|
||||
if (engineRange) {
|
||||
const found =
|
||||
|
||||
@@ -165,8 +165,8 @@ export function getSpawnOptions(
|
||||
export async function getNodeVersion(
|
||||
destPath: string,
|
||||
_nodeVersion?: string,
|
||||
_config?: Config,
|
||||
meta?: Meta
|
||||
config: Config = {},
|
||||
meta: Meta = {}
|
||||
): Promise<NodeVersion> {
|
||||
if (meta && meta.isDev) {
|
||||
// Use the system-installed version of `node` in PATH for `vercel dev`
|
||||
@@ -174,13 +174,22 @@ export async function getNodeVersion(
|
||||
return { ...latest, runtime: 'nodejs' };
|
||||
}
|
||||
const { packageJson } = await scanParentDirs(destPath, true);
|
||||
let range: string | undefined;
|
||||
let { nodeVersion } = config;
|
||||
let isAuto = true;
|
||||
if (packageJson && packageJson.engines && packageJson.engines.node) {
|
||||
range = packageJson.engines.node;
|
||||
if (
|
||||
nodeVersion &&
|
||||
nodeVersion !== packageJson.engines.node &&
|
||||
!meta.isDev
|
||||
) {
|
||||
console.warn(
|
||||
'Warning: Due to `engines` existing in your `package.json` file, the Node.js Version defined in your Project Settings will not apply. Learn More: http://vercel.link/node-version'
|
||||
);
|
||||
}
|
||||
nodeVersion = packageJson.engines.node;
|
||||
isAuto = false;
|
||||
}
|
||||
return getSupportedNodeVersion(range, isAuto);
|
||||
return getSupportedNodeVersion(nodeVersion, isAuto);
|
||||
}
|
||||
|
||||
async function scanParentDirs(destPath: string, readPackageJson = false) {
|
||||
|
||||
@@ -39,7 +39,7 @@ for (const fixture of fs.readdirSync(fixturesPath)) {
|
||||
|
||||
// few foreign tests
|
||||
|
||||
const buildersToTestWith = ['now-next', 'now-node', 'now-static-build'];
|
||||
const buildersToTestWith = ['now-node'];
|
||||
|
||||
// eslint-disable-next-line no-restricted-syntax
|
||||
for (const builder of buildersToTestWith) {
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"private": true,
|
||||
"engines": {
|
||||
"node": "14.x"
|
||||
}
|
||||
}
|
||||
70
packages/now-build-utils/test/unit.test.js
vendored
70
packages/now-build-utils/test/unit.test.js
vendored
@@ -24,6 +24,19 @@ async function expectBuilderError(promise, pattern) {
|
||||
);
|
||||
}
|
||||
|
||||
let warningMessages;
|
||||
const originalConsoleWarn = console.warn;
|
||||
beforeEach(() => {
|
||||
warningMessages = [];
|
||||
console.warn = m => {
|
||||
warningMessages.push(m);
|
||||
};
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
console.warn = originalConsoleWarn;
|
||||
});
|
||||
|
||||
it('should re-create symlinks properly', async () => {
|
||||
if (process.platform === 'win32') {
|
||||
console.log('Skipping test on windows');
|
||||
@@ -81,6 +94,10 @@ it('should only match supported node versions', async () => {
|
||||
'major',
|
||||
12
|
||||
);
|
||||
expect(await getSupportedNodeVersion('14.x', false)).toHaveProperty(
|
||||
'major',
|
||||
14
|
||||
);
|
||||
expect(getSupportedNodeVersion('8.11.x', false)).rejects.toThrow();
|
||||
expect(getSupportedNodeVersion('6.x', false)).rejects.toThrow();
|
||||
expect(getSupportedNodeVersion('999.x', false)).rejects.toThrow();
|
||||
@@ -104,6 +121,10 @@ it('should only match supported node versions', async () => {
|
||||
'major',
|
||||
12
|
||||
);
|
||||
expect(await getSupportedNodeVersion('14.x', true)).toHaveProperty(
|
||||
'major',
|
||||
14
|
||||
);
|
||||
const foundMessage = /Found `engines` in `package\.json` with an invalid Node\.js version range/;
|
||||
await expectBuilderError(
|
||||
getSupportedNodeVersion('8.11.x', false),
|
||||
@@ -125,8 +146,8 @@ it('should match all semver ranges', async () => {
|
||||
// See https://docs.npmjs.com/files/package.json#engines
|
||||
expect(await getSupportedNodeVersion('10.0.0')).toHaveProperty('major', 10);
|
||||
expect(await getSupportedNodeVersion('10.x')).toHaveProperty('major', 10);
|
||||
expect(await getSupportedNodeVersion('>=10')).toHaveProperty('major', 12);
|
||||
expect(await getSupportedNodeVersion('>=10.3.0')).toHaveProperty('major', 12);
|
||||
expect(await getSupportedNodeVersion('>=10')).toHaveProperty('major', 14);
|
||||
expect(await getSupportedNodeVersion('>=10.3.0')).toHaveProperty('major', 14);
|
||||
expect(await getSupportedNodeVersion('8.5.0 - 10.5.0')).toHaveProperty(
|
||||
'major',
|
||||
10
|
||||
@@ -150,20 +171,57 @@ it('should ignore node version in vercel dev getNodeVersion()', async () => {
|
||||
).toHaveProperty('runtime', 'nodejs');
|
||||
});
|
||||
|
||||
it('should select project setting from config when no package.json is found', async () => {
|
||||
expect(
|
||||
await getNodeVersion('/tmp', undefined, { nodeVersion: '14.x' }, {})
|
||||
).toHaveProperty('range', '14.x');
|
||||
expect(warningMessages).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it('should prefer package.json engines over project setting from config and warn', async () => {
|
||||
expect(
|
||||
await getNodeVersion(
|
||||
path.join(__dirname, 'pkg-engine-node'),
|
||||
undefined,
|
||||
{ nodeVersion: '12.x' },
|
||||
{}
|
||||
)
|
||||
).toHaveProperty('range', '14.x');
|
||||
expect(warningMessages).toStrictEqual([
|
||||
'Warning: Due to `engines` existing in your `package.json` file, the Node.js Version defined in your Project Settings will not apply. Learn More: http://vercel.link/node-version',
|
||||
]);
|
||||
});
|
||||
|
||||
it('should not warn when package.json engines matches project setting from config', async () => {
|
||||
expect(
|
||||
await getNodeVersion(
|
||||
path.join(__dirname, 'pkg-engine-node'),
|
||||
undefined,
|
||||
{ nodeVersion: '14.x' },
|
||||
{}
|
||||
)
|
||||
).toHaveProperty('range', '14.x');
|
||||
expect(warningMessages).toStrictEqual([]);
|
||||
});
|
||||
|
||||
it('should get latest node version', async () => {
|
||||
expect(await getLatestNodeVersion()).toHaveProperty('major', 12);
|
||||
expect(await getLatestNodeVersion()).toHaveProperty('major', 14);
|
||||
});
|
||||
|
||||
it('should throw for discontinued versions', async () => {
|
||||
// Mock a future date so that Node 8 becomes discontinued
|
||||
const realDateNow = Date.now.bind(global.Date);
|
||||
global.Date.now = () => new Date('2020-02-14').getTime();
|
||||
global.Date.now = () => new Date('2021-04-01').getTime();
|
||||
|
||||
expect(getSupportedNodeVersion('8.10.x', false)).rejects.toThrow();
|
||||
expect(getSupportedNodeVersion('8.10.x', true)).rejects.toThrow();
|
||||
expect(getSupportedNodeVersion('10.x', false)).rejects.toThrow();
|
||||
expect(getSupportedNodeVersion('10.x', true)).rejects.toThrow();
|
||||
|
||||
expect(getDiscontinuedNodeVersions().length).toBe(1);
|
||||
expect(getDiscontinuedNodeVersions()[0]).toHaveProperty('range', '8.10.x');
|
||||
const discontinued = getDiscontinuedNodeVersions();
|
||||
expect(discontinued.length).toBe(2);
|
||||
expect(discontinued[0]).toHaveProperty('range', '10.x');
|
||||
expect(discontinued[1]).toHaveProperty('range', '8.10.x');
|
||||
|
||||
global.Date.now = realDateNow;
|
||||
});
|
||||
|
||||
25
packages/now-cgi/build.js
Normal file
25
packages/now-cgi/build.js
Normal file
@@ -0,0 +1,25 @@
|
||||
#!/usr/bin/env node
|
||||
const execa = require('execa');
|
||||
const { join } = require('path');
|
||||
const { homedir } = require('os');
|
||||
|
||||
async function main() {
|
||||
process.env.GOOS = 'linux';
|
||||
process.env.GOARCH = 'amd64';
|
||||
process.env.GOPATH = join(homedir(), 'go');
|
||||
|
||||
await execa('go', ['get', 'github.com/aws/aws-lambda-go/events'], {
|
||||
stdio: 'inherit',
|
||||
});
|
||||
await execa('go', ['get', 'github.com/aws/aws-lambda-go/lambda'], {
|
||||
stdio: 'inherit',
|
||||
});
|
||||
await execa('go', ['build', '-o', 'handler', 'main.go'], {
|
||||
stdio: 'inherit',
|
||||
});
|
||||
}
|
||||
|
||||
main().catch(err => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -1,7 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
export GOOS=linux
|
||||
export GOARCH=amd64
|
||||
export GOPATH=$HOME/go
|
||||
go get github.com/aws/aws-lambda-go/events
|
||||
go get github.com/aws/aws-lambda-go/lambda
|
||||
go build -o handler main.go
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/cgi",
|
||||
"version": "1.0.6",
|
||||
"version": "1.0.7-canary.0",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -8,7 +8,8 @@
|
||||
"directory": "packages/now-cgi"
|
||||
},
|
||||
"scripts": {
|
||||
"prepublish": "./build.sh"
|
||||
"build": "node build",
|
||||
"prepublishOnly": "node build"
|
||||
},
|
||||
"files": [
|
||||
"index.js",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vercel",
|
||||
"version": "21.1.0",
|
||||
"version": "21.2.3",
|
||||
"preferGlobal": true,
|
||||
"license": "Apache-2.0",
|
||||
"description": "The command-line interface for Vercel",
|
||||
@@ -61,11 +61,11 @@
|
||||
"node": ">= 10"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/build-utils": "2.7.0",
|
||||
"@vercel/go": "1.1.7",
|
||||
"@vercel/node": "1.9.0",
|
||||
"@vercel/python": "1.2.4",
|
||||
"@vercel/ruby": "1.2.5",
|
||||
"@vercel/build-utils": "2.9.0",
|
||||
"@vercel/go": "1.1.8",
|
||||
"@vercel/node": "1.9.1-canary.0",
|
||||
"@vercel/python": "1.2.5-canary.1",
|
||||
"@vercel/ruby": "1.2.6-canary.0",
|
||||
"update-notifier": "4.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -2,7 +2,6 @@ import chalk from 'chalk';
|
||||
|
||||
import { handleError } from '../../util/error';
|
||||
|
||||
import createOutput from '../../util/output';
|
||||
import getArgs from '../../util/get-args';
|
||||
import getSubcommand from '../../util/get-subcommand';
|
||||
import logo from '../../util/output/logo';
|
||||
@@ -92,15 +91,14 @@ export default async function main(ctx) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
const output = createOutput({ debug: argv['--debug'] });
|
||||
const { subcommand, args } = getSubcommand(argv._.slice(1), COMMAND_CONFIG);
|
||||
|
||||
switch (subcommand) {
|
||||
case 'ls':
|
||||
return ls(ctx, argv, args, output);
|
||||
return ls(ctx, argv, args);
|
||||
case 'rm':
|
||||
return rm(ctx, argv, args, output);
|
||||
return rm(ctx, argv, args);
|
||||
default:
|
||||
return set(ctx, argv, args, output);
|
||||
return set(ctx, argv, args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,9 +10,10 @@ import strlen from '../../util/strlen.ts';
|
||||
import getCommandFlags from '../../util/get-command-flags';
|
||||
import { getCommandName } from '../../util/pkg-name.ts';
|
||||
|
||||
export default async function ls(ctx, opts, args, output) {
|
||||
export default async function ls(ctx, opts, args) {
|
||||
const {
|
||||
authConfig: { token },
|
||||
output,
|
||||
config,
|
||||
} = ctx;
|
||||
const { currentTeam } = config;
|
||||
@@ -23,6 +24,7 @@ export default async function ls(ctx, opts, args, output) {
|
||||
token,
|
||||
currentTeam,
|
||||
debug: debugEnabled,
|
||||
output,
|
||||
});
|
||||
let contextName = null;
|
||||
|
||||
@@ -47,9 +49,9 @@ export default async function ls(ctx, opts, args, output) {
|
||||
token,
|
||||
debug: debugEnabled,
|
||||
currentTeam,
|
||||
output,
|
||||
});
|
||||
const lsStamp = stamp();
|
||||
let cancelWait;
|
||||
|
||||
if (args.length > 0) {
|
||||
output.error(
|
||||
@@ -60,17 +62,13 @@ export default async function ls(ctx, opts, args, output) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
cancelWait = output.spinner(
|
||||
`Fetching aliases under ${chalk.bold(contextName)}`
|
||||
);
|
||||
output.spinner(`Fetching aliases under ${chalk.bold(contextName)}`);
|
||||
|
||||
const { aliases, pagination } = await getAliases(
|
||||
now,
|
||||
undefined,
|
||||
nextTimestamp
|
||||
);
|
||||
if (cancelWait) cancelWait();
|
||||
|
||||
output.log(`aliases found under ${chalk.bold(contextName)} ${lsStamp()}`);
|
||||
console.log(printAliasTable(aliases));
|
||||
|
||||
|
||||
@@ -12,9 +12,10 @@ import { isValidName } from '../../util/is-valid-name';
|
||||
import findAliasByAliasOrId from '../../util/alias/find-alias-by-alias-or-id';
|
||||
import { getCommandName } from '../../util/pkg-name.ts';
|
||||
|
||||
export default async function rm(ctx, opts, args, output) {
|
||||
export default async function rm(ctx, opts, args) {
|
||||
const {
|
||||
authConfig: { token },
|
||||
output,
|
||||
config,
|
||||
} = ctx;
|
||||
const { currentTeam } = config;
|
||||
@@ -25,6 +26,7 @@ export default async function rm(ctx, opts, args, output) {
|
||||
token,
|
||||
currentTeam,
|
||||
debug: debugEnabled,
|
||||
output,
|
||||
});
|
||||
let contextName = null;
|
||||
|
||||
@@ -39,8 +41,13 @@ export default async function rm(ctx, opts, args, output) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
// $FlowFixMe
|
||||
const now = new Now({ apiUrl, token, debug: debugEnabled, currentTeam });
|
||||
const now = new Now({
|
||||
apiUrl,
|
||||
token,
|
||||
debug: debugEnabled,
|
||||
currentTeam,
|
||||
output,
|
||||
});
|
||||
const [aliasOrId] = args;
|
||||
|
||||
if (args.length !== 1) {
|
||||
|
||||
@@ -29,11 +29,11 @@ type Options = {
|
||||
export default async function set(
|
||||
ctx: NowContext,
|
||||
opts: Options,
|
||||
args: string[],
|
||||
output: Output
|
||||
args: string[]
|
||||
) {
|
||||
const {
|
||||
authConfig: { token },
|
||||
output,
|
||||
config,
|
||||
localConfig,
|
||||
} = ctx;
|
||||
@@ -49,6 +49,7 @@ export default async function set(
|
||||
token,
|
||||
currentTeam,
|
||||
debug: debugEnabled,
|
||||
output,
|
||||
});
|
||||
|
||||
let user: User;
|
||||
|
||||
@@ -14,7 +14,6 @@ import addBilling from './add';
|
||||
import exit from '../../util/exit';
|
||||
import Client from '../../util/client.ts';
|
||||
import getScope from '../../util/get-scope.ts';
|
||||
import createOutput from '../../util/output';
|
||||
import { getPkgName } from '../../util/pkg-name.ts';
|
||||
|
||||
const help = () => {
|
||||
@@ -90,8 +89,9 @@ function buildInquirerChoices(cards) {
|
||||
const _default =
|
||||
source.id === cards.defaultSource ? ` ${chalk.bold('(default)')}` : '';
|
||||
const id = `${chalk.cyan(`ID: ${source.id}`)}${_default}`;
|
||||
const number = `${chalk.gray('#### ').repeat(3)}${source.last4 ||
|
||||
source.card.last4}`;
|
||||
const number = `${chalk.gray('#### ').repeat(3)}${
|
||||
source.last4 || source.card.last4
|
||||
}`;
|
||||
const str = [
|
||||
id,
|
||||
indent(source.name || source.owner.name, 2),
|
||||
@@ -106,11 +106,16 @@ function buildInquirerChoices(cards) {
|
||||
});
|
||||
}
|
||||
|
||||
async function run({ token, config: { currentTeam } }) {
|
||||
async function run({ token, output, config: { currentTeam } }) {
|
||||
const start = new Date();
|
||||
const creditCards = new NowCreditCards({ apiUrl, token, debug, currentTeam });
|
||||
const output = createOutput({ debug });
|
||||
const client = new Client({ apiUrl, token, currentTeam, debug });
|
||||
const creditCards = new NowCreditCards({
|
||||
apiUrl,
|
||||
token,
|
||||
debug,
|
||||
currentTeam,
|
||||
output,
|
||||
});
|
||||
const client = new Client({ apiUrl, token, currentTeam, debug, output });
|
||||
let contextName = null;
|
||||
|
||||
try {
|
||||
@@ -147,8 +152,9 @@ async function run({ token, config: { currentTeam } }) {
|
||||
const id = `${chalk.gray('-')} ${chalk.cyan(
|
||||
`ID: ${source.id}`
|
||||
)}${_default}`;
|
||||
const number = `${chalk.gray('#### ').repeat(3)}${source.last4 ||
|
||||
source.card.last4}`;
|
||||
const number = `${chalk.gray('#### ').repeat(3)}${
|
||||
source.last4 || source.card.last4
|
||||
}`;
|
||||
|
||||
return [
|
||||
id,
|
||||
@@ -231,8 +237,9 @@ async function run({ token, config: { currentTeam } }) {
|
||||
const elapsed = ms(new Date() - start);
|
||||
console.log(
|
||||
success(
|
||||
`${card.brand || card.card.brand} ending in ${card.last4 ||
|
||||
card.card.last4} is now the default ${chalk.gray(`[${elapsed}]`)}`
|
||||
`${card.brand || card.card.brand} ending in ${
|
||||
card.last4 || card.card.last4
|
||||
} is now the default ${chalk.gray(`[${elapsed}]`)}`
|
||||
)
|
||||
);
|
||||
} else {
|
||||
@@ -301,9 +308,9 @@ async function run({ token, config: { currentTeam } }) {
|
||||
const deletedCard = cards.sources.find(card => card.id === cardId);
|
||||
const remainingCards = cards.sources.filter(card => card.id !== cardId);
|
||||
|
||||
let text = `${deletedCard.brand ||
|
||||
deletedCard.card.brand} ending in ${deletedCard.last4 ||
|
||||
deletedCard.card.last4} was deleted`;
|
||||
let text = `${deletedCard.brand || deletedCard.card.brand} ending in ${
|
||||
deletedCard.last4 || deletedCard.card.last4
|
||||
} was deleted`;
|
||||
// ${chalk.gray(`[${elapsed}]`)}
|
||||
|
||||
if (cardId === cards.defaultSource) {
|
||||
@@ -317,11 +324,11 @@ async function run({ token, config: { currentTeam } }) {
|
||||
card => card.id === cards.defaultCardId
|
||||
);
|
||||
|
||||
text += `\n${newDefaultCard.brand ||
|
||||
newDefaultCard.card.brand} ending in ${newDefaultCard.last4 ||
|
||||
newDefaultCard.card.last4} in now default for ${chalk.bold(
|
||||
contextName
|
||||
)}`;
|
||||
text += `\n${
|
||||
newDefaultCard.brand || newDefaultCard.card.brand
|
||||
} ending in ${
|
||||
newDefaultCard.last4 || newDefaultCard.card.last4
|
||||
} in now default for ${chalk.bold(contextName)}`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ import stamp from '../../util/output/stamp';
|
||||
import createCertFromFile from '../../util/certs/create-cert-from-file';
|
||||
import createCertForCns from '../../util/certs/create-cert-for-cns';
|
||||
import { NowContext } from '../../types';
|
||||
import { Output } from '../../util/output';
|
||||
import { getCommandName } from '../../util/pkg-name';
|
||||
|
||||
interface Options {
|
||||
@@ -22,11 +21,11 @@ interface Options {
|
||||
async function add(
|
||||
ctx: NowContext,
|
||||
opts: Options,
|
||||
args: string[],
|
||||
output: Output
|
||||
args: string[]
|
||||
): Promise<number> {
|
||||
const {
|
||||
authConfig: { token },
|
||||
output,
|
||||
config,
|
||||
} = ctx;
|
||||
const { currentTeam } = config;
|
||||
@@ -49,6 +48,7 @@ async function add(
|
||||
token,
|
||||
currentTeam,
|
||||
debug: debugEnabled,
|
||||
output,
|
||||
});
|
||||
|
||||
try {
|
||||
@@ -62,7 +62,13 @@ async function add(
|
||||
throw err;
|
||||
}
|
||||
|
||||
const now = new Now({ apiUrl, token, debug: debugEnabled, currentTeam });
|
||||
const now = new Now({
|
||||
apiUrl,
|
||||
token,
|
||||
debug: debugEnabled,
|
||||
currentTeam,
|
||||
output,
|
||||
});
|
||||
|
||||
if (overwite) {
|
||||
output.error('Overwrite option is deprecated');
|
||||
@@ -71,7 +77,7 @@ async function add(
|
||||
}
|
||||
|
||||
if (crtPath || keyPath || caPath) {
|
||||
if (args.length !== 0 || (!crtPath || !keyPath || !caPath)) {
|
||||
if (args.length !== 0 || !crtPath || !keyPath || !caPath) {
|
||||
output.error(
|
||||
`Invalid number of arguments to create a custom certificate entry. Usage:`
|
||||
);
|
||||
@@ -113,12 +119,12 @@ async function add(
|
||||
(res, item) => res.concat(item.split(',')),
|
||||
[]
|
||||
);
|
||||
const cancelWait = output.spinner(
|
||||
output.spinner(
|
||||
`Generating a certificate for ${chalk.bold(cns.join(', '))}`
|
||||
);
|
||||
|
||||
cert = await createCertForCns(now, cns, contextName);
|
||||
cancelWait();
|
||||
output.stopSpinner();
|
||||
}
|
||||
|
||||
if (cert instanceof Error) {
|
||||
|
||||
@@ -3,7 +3,6 @@ import chalk from 'chalk';
|
||||
// @ts-ignore
|
||||
import { handleError } from '../../util/error';
|
||||
|
||||
import createOutput from '../../util/output';
|
||||
import getArgs from '../../util/get-args';
|
||||
import getSubcommand from '../../util/get-subcommand';
|
||||
import logo from '../../util/output/logo';
|
||||
@@ -104,17 +103,17 @@ export default async function main(ctx: NowContext) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const output = createOutput({ debug: argv['--debug'] });
|
||||
const { output } = ctx;
|
||||
const { subcommand, args } = getSubcommand(argv._.slice(1), COMMAND_CONFIG);
|
||||
switch (subcommand) {
|
||||
case 'issue':
|
||||
return issue(ctx, argv, args, output);
|
||||
return issue(ctx, argv, args);
|
||||
case 'ls':
|
||||
return ls(ctx, argv, args, output);
|
||||
return ls(ctx, argv, args);
|
||||
case 'rm':
|
||||
return rm(ctx, argv, args, output);
|
||||
return rm(ctx, argv, args);
|
||||
case 'add':
|
||||
return add(ctx, argv, args, output);
|
||||
return add(ctx, argv, args);
|
||||
case 'renew':
|
||||
output.error('Renewing certificates is deprecated, issue a new one.');
|
||||
return 1;
|
||||
|
||||
@@ -28,11 +28,11 @@ type Options = {
|
||||
export default async function issue(
|
||||
ctx: NowContext,
|
||||
opts: Options,
|
||||
args: string[],
|
||||
output: Output
|
||||
args: string[]
|
||||
) {
|
||||
const {
|
||||
authConfig: { token },
|
||||
output,
|
||||
config,
|
||||
} = ctx;
|
||||
const { currentTeam } = config;
|
||||
@@ -55,6 +55,7 @@ export default async function issue(
|
||||
token,
|
||||
currentTeam,
|
||||
debug: debugEnabled,
|
||||
output,
|
||||
});
|
||||
let contextName = null;
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ import getScope from '../../util/get-scope';
|
||||
import stamp from '../../util/output/stamp';
|
||||
import getCerts from '../../util/certs/get-certs';
|
||||
import strlen from '../../util/strlen';
|
||||
import { Output } from '../../util/output';
|
||||
import { NowContext, Cert } from '../../types';
|
||||
import getCommandFlags from '../../util/get-command-flags';
|
||||
import { getCommandName } from '../../util/pkg-name';
|
||||
@@ -21,17 +20,17 @@ interface Options {
|
||||
async function ls(
|
||||
ctx: NowContext,
|
||||
opts: Options,
|
||||
args: string[],
|
||||
output: Output
|
||||
args: string[]
|
||||
): Promise<number> {
|
||||
const {
|
||||
authConfig: { token },
|
||||
output,
|
||||
config,
|
||||
} = ctx;
|
||||
const { currentTeam } = config;
|
||||
const { apiUrl } = ctx;
|
||||
const { '--debug': debug, '--next': nextTimestamp } = opts;
|
||||
const client = new Client({ apiUrl, token, currentTeam, debug });
|
||||
const client = new Client({ apiUrl, token, currentTeam, debug, output });
|
||||
let contextName = null;
|
||||
|
||||
try {
|
||||
@@ -48,7 +47,7 @@ async function ls(
|
||||
output.error('Please provide a number for flag --next');
|
||||
return 1;
|
||||
}
|
||||
const now = new Now({ apiUrl, token, debug, currentTeam });
|
||||
const now = new Now({ apiUrl, token, debug, currentTeam, output });
|
||||
const lsStamp = stamp();
|
||||
|
||||
if (args.length !== 0) {
|
||||
|
||||
@@ -18,21 +18,17 @@ type Options = {
|
||||
'--debug': boolean;
|
||||
};
|
||||
|
||||
async function rm(
|
||||
ctx: NowContext,
|
||||
opts: Options,
|
||||
args: string[],
|
||||
output: Output
|
||||
) {
|
||||
async function rm(ctx: NowContext, opts: Options, args: string[]) {
|
||||
const {
|
||||
authConfig: { token },
|
||||
output,
|
||||
config,
|
||||
} = ctx;
|
||||
const { currentTeam } = config;
|
||||
const { apiUrl } = ctx;
|
||||
const rmStamp = stamp();
|
||||
const debug = opts['--debug'];
|
||||
const client = new Client({ apiUrl, token, currentTeam, debug });
|
||||
const client = new Client({ apiUrl, token, currentTeam, debug, output });
|
||||
|
||||
let contextName = null;
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ import { resolve, basename } from 'path';
|
||||
import { fileNameSymbol } from '@vercel/client';
|
||||
import Client from '../../util/client.ts';
|
||||
import getScope from '../../util/get-scope.ts';
|
||||
import createOutput from '../../util/output';
|
||||
import code from '../../util/output/code';
|
||||
import highlight from '../../util/output/highlight';
|
||||
import { readLocalConfig } from '../../util/config/files';
|
||||
@@ -15,6 +14,7 @@ import deploy from './latest';
|
||||
export default async ctx => {
|
||||
const {
|
||||
authConfig,
|
||||
output,
|
||||
config: { currentTeam },
|
||||
apiUrl,
|
||||
} = ctx;
|
||||
@@ -48,7 +48,6 @@ export default async ctx => {
|
||||
localConfig = readLocalConfig(paths[0]);
|
||||
}
|
||||
const debugEnabled = argv['--debug'];
|
||||
const output = createOutput({ debug: debugEnabled });
|
||||
const stats = {};
|
||||
|
||||
if (argv['--help']) {
|
||||
@@ -74,6 +73,7 @@ export default async ctx => {
|
||||
apiUrl,
|
||||
token: authConfig.token,
|
||||
currentTeam,
|
||||
output,
|
||||
debug: debugEnabled,
|
||||
});
|
||||
try {
|
||||
|
||||
@@ -233,8 +233,7 @@ export default async function main(
|
||||
const paths = Object.keys(stats);
|
||||
const debugEnabled = argv['--debug'];
|
||||
|
||||
// $FlowFixMe
|
||||
const isTTY = process.stdout.isTTY;
|
||||
const { isTTY } = process.stdout;
|
||||
const quiet = !isTTY;
|
||||
|
||||
// check paths
|
||||
@@ -263,6 +262,7 @@ export default async function main(
|
||||
apiUrl: ctx.apiUrl,
|
||||
token: ctx.authConfig.token,
|
||||
debug: debugEnabled,
|
||||
output,
|
||||
});
|
||||
|
||||
// retrieve `project` and `org` from .vercel
|
||||
@@ -645,6 +645,7 @@ export default async function main(
|
||||
token: ctx.authConfig.token,
|
||||
currentTeam: org.id,
|
||||
debug: debugEnabled,
|
||||
output,
|
||||
}),
|
||||
err.meta.domain,
|
||||
contextName
|
||||
@@ -727,6 +728,7 @@ export default async function main(
|
||||
token: ctx.authConfig.token,
|
||||
currentTeam: org.type === 'team' ? org.id : null,
|
||||
debug: debugEnabled,
|
||||
output,
|
||||
}),
|
||||
deployment,
|
||||
deployStamp,
|
||||
|
||||
@@ -2,7 +2,6 @@ import { resolve, join } from 'path';
|
||||
|
||||
import DevServer from '../../util/dev/server';
|
||||
import parseListen from '../../util/dev/parse-listen';
|
||||
import { Output } from '../../util/output';
|
||||
import { NowContext, ProjectEnvVariable } from '../../types';
|
||||
import Client from '../../util/client';
|
||||
import { getLinkedProject } from '../../util/projects/link';
|
||||
@@ -22,9 +21,9 @@ type Options = {
|
||||
export default async function dev(
|
||||
ctx: NowContext,
|
||||
opts: Options,
|
||||
args: string[],
|
||||
output: Output
|
||||
args: string[]
|
||||
) {
|
||||
const { output } = ctx;
|
||||
const [dir = '.'] = args;
|
||||
let cwd = resolve(dir);
|
||||
const listen = parseListen(opts['--listen'] || '3000');
|
||||
@@ -35,6 +34,7 @@ export default async function dev(
|
||||
token: ctx.authConfig.token,
|
||||
currentTeam: ctx.config.currentTeam,
|
||||
debug,
|
||||
output,
|
||||
});
|
||||
|
||||
// retrieve dev command
|
||||
@@ -49,7 +49,6 @@ export default async function dev(
|
||||
|
||||
link = await setupAndLink(
|
||||
ctx,
|
||||
output,
|
||||
cwd,
|
||||
forceDelete,
|
||||
autoConfirm,
|
||||
|
||||
@@ -7,7 +7,6 @@ import getSubcommand from '../../util/get-subcommand';
|
||||
import { NowContext } from '../../types';
|
||||
import { NowError } from '../../util/now-error';
|
||||
import handleError from '../../util/handle-error';
|
||||
import createOutput from '../../util/output/create-output';
|
||||
import logo from '../../util/output/logo';
|
||||
import cmd from '../../util/output/cmd';
|
||||
import highlight from '../../util/output/highlight';
|
||||
@@ -51,7 +50,7 @@ const help = () => {
|
||||
export default async function main(ctx: NowContext) {
|
||||
let argv;
|
||||
let args;
|
||||
let output;
|
||||
const { output } = ctx;
|
||||
|
||||
try {
|
||||
argv = getArgs(ctx.argv.slice(2), {
|
||||
@@ -63,9 +62,7 @@ export default async function main(ctx: NowContext) {
|
||||
'--port': Number,
|
||||
'-p': '--port',
|
||||
});
|
||||
const debug = argv['--debug'];
|
||||
args = getSubcommand(argv._.slice(1), COMMAND_CONFIG).args;
|
||||
output = createOutput({ debug });
|
||||
|
||||
if ('--port' in argv) {
|
||||
output.warn('`--port` is deprecated, please use `--listen` instead');
|
||||
@@ -120,7 +117,7 @@ export default async function main(ctx: NowContext) {
|
||||
}
|
||||
|
||||
try {
|
||||
return await dev(ctx, argv, args, output);
|
||||
return await dev(ctx, argv, args);
|
||||
} catch (err) {
|
||||
if (err.code === 'ENOTFOUND') {
|
||||
// Error message will look like the following:
|
||||
|
||||
@@ -6,7 +6,6 @@ import {
|
||||
DNSInvalidType,
|
||||
} from '../../util/errors-ts';
|
||||
import { NowContext } from '../../types';
|
||||
import { Output } from '../../util/output';
|
||||
import addDNSRecord from '../../util/dns/add-dns-record';
|
||||
import Client from '../../util/client';
|
||||
import getScope from '../../util/get-scope';
|
||||
@@ -22,17 +21,17 @@ type Options = {
|
||||
export default async function add(
|
||||
ctx: NowContext,
|
||||
opts: Options,
|
||||
args: string[],
|
||||
output: Output
|
||||
args: string[]
|
||||
) {
|
||||
const {
|
||||
apiUrl,
|
||||
authConfig: { token },
|
||||
output,
|
||||
config,
|
||||
} = ctx;
|
||||
const { currentTeam } = config;
|
||||
const { apiUrl } = ctx;
|
||||
const debug = opts['--debug'];
|
||||
const client = new Client({ apiUrl, token, currentTeam, debug });
|
||||
const client = new Client({ apiUrl, token, currentTeam, debug, output });
|
||||
let contextName = null;
|
||||
|
||||
try {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import chalk from 'chalk';
|
||||
import { NowContext } from '../../types';
|
||||
import { Output } from '../../util/output';
|
||||
import Client from '../../util/client';
|
||||
import getScope from '../../util/get-scope';
|
||||
import { DomainNotFound, InvalidDomain } from '../../util/errors-ts';
|
||||
@@ -15,17 +14,17 @@ type Options = {
|
||||
export default async function add(
|
||||
ctx: NowContext,
|
||||
opts: Options,
|
||||
args: string[],
|
||||
output: Output
|
||||
args: string[]
|
||||
) {
|
||||
const {
|
||||
apiUrl,
|
||||
authConfig: { token },
|
||||
output,
|
||||
config,
|
||||
} = ctx;
|
||||
const { currentTeam } = config;
|
||||
const { apiUrl } = ctx;
|
||||
const debug = opts['--debug'];
|
||||
const client = new Client({ apiUrl, token, currentTeam, debug });
|
||||
const client = new Client({ apiUrl, token, currentTeam, debug, output });
|
||||
let contextName = null;
|
||||
|
||||
try {
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import chalk from 'chalk';
|
||||
|
||||
import { NowContext } from '../../types';
|
||||
import createOutput from '../../util/output';
|
||||
import getArgs from '../../util/get-args';
|
||||
import getSubcommand from '../../util/get-subcommand';
|
||||
import handleError from '../../util/handle-error';
|
||||
@@ -112,16 +111,15 @@ export default async function main(ctx: NowContext) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
const output = createOutput({ debug: argv['--debug'] });
|
||||
const { subcommand, args } = getSubcommand(argv._.slice(1), COMMAND_CONFIG);
|
||||
switch (subcommand) {
|
||||
case 'add':
|
||||
return add(ctx, argv, args, output);
|
||||
return add(ctx, argv, args);
|
||||
case 'import':
|
||||
return importZone(ctx, argv, args, output);
|
||||
return importZone(ctx, argv, args);
|
||||
case 'rm':
|
||||
return rm(ctx, argv, args, output);
|
||||
return rm(ctx, argv, args);
|
||||
default:
|
||||
return ls(ctx, argv, args, output);
|
||||
return ls(ctx, argv, args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import chalk from 'chalk';
|
||||
import ms from 'ms';
|
||||
import { Output } from '../../util/output';
|
||||
import { DomainNotFound } from '../../util/errors-ts';
|
||||
import { DNSRecord, NowContext } from '../../types';
|
||||
import Client from '../../util/client';
|
||||
@@ -22,17 +21,17 @@ type Options = {
|
||||
export default async function ls(
|
||||
ctx: NowContext,
|
||||
opts: Options,
|
||||
args: string[],
|
||||
output: Output
|
||||
args: string[]
|
||||
) {
|
||||
const {
|
||||
apiUrl,
|
||||
authConfig: { token },
|
||||
output,
|
||||
config,
|
||||
} = ctx;
|
||||
const { currentTeam } = config;
|
||||
const { apiUrl } = ctx;
|
||||
const { '--debug': debug, '--next': nextTimestamp } = opts;
|
||||
const client = new Client({ apiUrl, token, currentTeam, debug });
|
||||
const client = new Client({ apiUrl, token, currentTeam, debug, output });
|
||||
let contextName = null;
|
||||
|
||||
try {
|
||||
|
||||
@@ -17,17 +17,17 @@ type Options = {
|
||||
export default async function rm(
|
||||
ctx: NowContext,
|
||||
opts: Options,
|
||||
args: string[],
|
||||
output: Output
|
||||
args: string[]
|
||||
) {
|
||||
const {
|
||||
apiUrl,
|
||||
authConfig: { token },
|
||||
output,
|
||||
config,
|
||||
} = ctx;
|
||||
const { currentTeam } = config;
|
||||
const { apiUrl } = ctx;
|
||||
const debug = opts['--debug'];
|
||||
const client = new Client({ apiUrl, token, currentTeam, debug });
|
||||
const client = new Client({ apiUrl, token, currentTeam, debug, output });
|
||||
|
||||
try {
|
||||
await getScope(client);
|
||||
@@ -100,12 +100,7 @@ function readConfirmation(
|
||||
process.stdin
|
||||
.on('data', d => {
|
||||
process.stdin.pause();
|
||||
resolve(
|
||||
d
|
||||
.toString()
|
||||
.trim()
|
||||
.toLowerCase() === 'y'
|
||||
);
|
||||
resolve(d.toString().trim().toLowerCase() === 'y');
|
||||
})
|
||||
.resume();
|
||||
});
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import chalk from 'chalk';
|
||||
|
||||
import { NowContext } from '../../types';
|
||||
import { Output } from '../../util/output';
|
||||
import * as ERRORS from '../../util/errors-ts';
|
||||
import Client from '../../util/client';
|
||||
import formatNSTable from '../../util/format-ns-table';
|
||||
@@ -24,18 +23,18 @@ type Options = {
|
||||
export default async function add(
|
||||
ctx: NowContext,
|
||||
opts: Options,
|
||||
args: string[],
|
||||
output: Output
|
||||
args: string[]
|
||||
) {
|
||||
const {
|
||||
authConfig: { token },
|
||||
output,
|
||||
config,
|
||||
} = ctx;
|
||||
const { currentTeam } = config;
|
||||
const { apiUrl } = ctx;
|
||||
const debug = opts['--debug'];
|
||||
const force = opts['--force'];
|
||||
const client = new Client({ apiUrl, token, currentTeam, debug });
|
||||
const client = new Client({ apiUrl, token, currentTeam, debug, output });
|
||||
let contextName = null;
|
||||
|
||||
try {
|
||||
|
||||
@@ -2,7 +2,6 @@ import chalk from 'chalk';
|
||||
import psl from 'psl';
|
||||
|
||||
import { NowContext } from '../../types';
|
||||
import { Output } from '../../util/output';
|
||||
import * as ERRORS from '../../util/errors-ts';
|
||||
import Client from '../../util/client';
|
||||
import getDomainPrice from '../../util/domains/get-domain-price';
|
||||
@@ -21,17 +20,17 @@ type Options = {
|
||||
export default async function buy(
|
||||
ctx: NowContext,
|
||||
opts: Options,
|
||||
args: string[],
|
||||
output: Output
|
||||
args: string[]
|
||||
) {
|
||||
const {
|
||||
authConfig: { token },
|
||||
output,
|
||||
config,
|
||||
} = ctx;
|
||||
const { currentTeam } = config;
|
||||
const { apiUrl } = ctx;
|
||||
const debug = opts['--debug'];
|
||||
const client = new Client({ apiUrl, token, currentTeam, debug });
|
||||
const client = new Client({ apiUrl, token, currentTeam, debug, output });
|
||||
let contextName = null;
|
||||
|
||||
try {
|
||||
@@ -70,7 +69,10 @@ export default async function buy(
|
||||
}
|
||||
|
||||
const availableStamp = stamp();
|
||||
const domainPrice = await getDomainPrice(client, domainName);
|
||||
const [domainPrice, renewalPrice] = await Promise.all([
|
||||
getDomainPrice(client, domainName),
|
||||
getDomainPrice(client, domainName, 'renewal'),
|
||||
]);
|
||||
|
||||
if (domainPrice instanceof Error) {
|
||||
output.prettyError(domainPrice);
|
||||
@@ -102,14 +104,22 @@ export default async function buy(
|
||||
return 0;
|
||||
}
|
||||
|
||||
const autoRenew = await promptBool(
|
||||
renewalPrice.period === 1
|
||||
? `Auto renew yearly for ${chalk.bold(`$${price}`)}?`
|
||||
: `Auto renew every ${renewalPrice.period} years for ${chalk.bold(
|
||||
`$${price}`
|
||||
)}?`,
|
||||
{ defaultValue: true }
|
||||
);
|
||||
|
||||
let buyResult;
|
||||
const purchaseStamp = stamp();
|
||||
const stopPurchaseSpinner = output.spinner('Purchasing');
|
||||
output.spinner('Purchasing');
|
||||
|
||||
try {
|
||||
buyResult = await purchaseDomain(client, domainName, price);
|
||||
buyResult = await purchaseDomain(client, domainName, price, autoRenew);
|
||||
} catch (err) {
|
||||
stopPurchaseSpinner();
|
||||
output.error(
|
||||
'An unexpected error occurred while purchasing your domain. Please try again later.'
|
||||
);
|
||||
@@ -117,7 +127,7 @@ export default async function buy(
|
||||
return 1;
|
||||
}
|
||||
|
||||
stopPurchaseSpinner();
|
||||
output.stopSpinner();
|
||||
|
||||
if (buyResult instanceof ERRORS.SourceNotFound) {
|
||||
output.error(
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import chalk from 'chalk';
|
||||
|
||||
import { NowContext } from '../../types';
|
||||
import createOutput from '../../util/output';
|
||||
import getArgs from '../../util/get-args';
|
||||
import getSubcommand from '../../util/get-subcommand';
|
||||
import handleError from '../../util/handle-error';
|
||||
@@ -106,24 +105,23 @@ export default async function main(ctx: NowContext) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
const output = createOutput({ debug: argv['--debug'] });
|
||||
const { subcommand, args } = getSubcommand(argv._.slice(1), COMMAND_CONFIG);
|
||||
switch (subcommand) {
|
||||
case 'add':
|
||||
return add(ctx, argv, args, output);
|
||||
return add(ctx, argv, args);
|
||||
case 'inspect':
|
||||
return inspect(ctx, argv, args, output);
|
||||
return inspect(ctx, argv, args);
|
||||
case 'move':
|
||||
return move(ctx, argv, args, output);
|
||||
return move(ctx, argv, args);
|
||||
case 'buy':
|
||||
return buy(ctx, argv, args, output);
|
||||
return buy(ctx, argv, args);
|
||||
case 'rm':
|
||||
return rm(ctx, argv, args, output);
|
||||
return rm(ctx, argv, args);
|
||||
case 'transferIn':
|
||||
return transferIn(ctx, argv, args, output);
|
||||
return transferIn(ctx, argv, args);
|
||||
case 'verify':
|
||||
return verify(ctx, argv, args, output);
|
||||
return verify(ctx, argv, args);
|
||||
default:
|
||||
return ls(ctx, argv, args, output);
|
||||
return ls(ctx, argv, args);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,17 +24,17 @@ type Options = {
|
||||
export default async function inspect(
|
||||
ctx: NowContext,
|
||||
opts: Options,
|
||||
args: string[],
|
||||
output: Output
|
||||
args: string[]
|
||||
) {
|
||||
const {
|
||||
authConfig: { token },
|
||||
output,
|
||||
config,
|
||||
} = ctx;
|
||||
const { currentTeam } = config;
|
||||
const { apiUrl } = ctx;
|
||||
const debug = opts['--debug'];
|
||||
const client = new Client({ apiUrl, token, currentTeam, debug });
|
||||
const client = new Client({ apiUrl, token, currentTeam, debug, output });
|
||||
|
||||
let contextName = null;
|
||||
|
||||
|
||||
@@ -7,7 +7,6 @@ import Client from '../../util/client';
|
||||
import getDomains from '../../util/domains/get-domains';
|
||||
import getScope from '../../util/get-scope';
|
||||
import stamp from '../../util/output/stamp';
|
||||
import { Output } from '../../util/output';
|
||||
import formatTable from '../../util/format-table';
|
||||
import { formatDateWithoutTime } from '../../util/format-date';
|
||||
import { Domain, NowContext } from '../../types';
|
||||
@@ -24,17 +23,17 @@ type Options = {
|
||||
export default async function ls(
|
||||
ctx: NowContext,
|
||||
opts: Options,
|
||||
args: string[],
|
||||
output: Output
|
||||
args: string[]
|
||||
) {
|
||||
const {
|
||||
authConfig: { token },
|
||||
output,
|
||||
config,
|
||||
} = ctx;
|
||||
const { currentTeam } = config;
|
||||
const { apiUrl } = ctx;
|
||||
const { '--debug': debug, '--next': nextTimestamp } = opts;
|
||||
const client = new Client({ apiUrl, token, currentTeam, debug });
|
||||
const client = new Client({ apiUrl, token, currentTeam, debug, output });
|
||||
let contextName = null;
|
||||
|
||||
if (typeof nextTimestamp !== undefined && Number.isNaN(nextTimestamp)) {
|
||||
|
||||
@@ -2,7 +2,6 @@ import chalk from 'chalk';
|
||||
import plural from 'pluralize';
|
||||
|
||||
import { NowContext, User, Team } from '../../types';
|
||||
import { Output } from '../../util/output';
|
||||
import * as ERRORS from '../../util/errors-ts';
|
||||
import Client from '../../util/client';
|
||||
import getScope from '../../util/get-scope';
|
||||
@@ -25,17 +24,17 @@ type Options = {
|
||||
export default async function move(
|
||||
ctx: NowContext,
|
||||
opts: Options,
|
||||
args: string[],
|
||||
output: Output
|
||||
args: string[]
|
||||
) {
|
||||
const {
|
||||
authConfig: { token },
|
||||
output,
|
||||
config,
|
||||
} = ctx;
|
||||
const { currentTeam } = config;
|
||||
const { apiUrl } = ctx;
|
||||
const debug = opts['--debug'];
|
||||
const client = new Client({ apiUrl, token, currentTeam, debug });
|
||||
const client = new Client({ apiUrl, token, currentTeam, debug, output });
|
||||
let contextName = null;
|
||||
let user = null;
|
||||
|
||||
|
||||
@@ -26,17 +26,17 @@ type Options = {
|
||||
export default async function rm(
|
||||
ctx: NowContext,
|
||||
opts: Options,
|
||||
args: string[],
|
||||
output: Output
|
||||
args: string[]
|
||||
) {
|
||||
const {
|
||||
authConfig: { token },
|
||||
output,
|
||||
config,
|
||||
} = ctx;
|
||||
const { currentTeam } = config;
|
||||
const { apiUrl } = ctx;
|
||||
const debug = opts['--debug'];
|
||||
const client = new Client({ apiUrl, token, currentTeam, debug });
|
||||
const client = new Client({ apiUrl, token, currentTeam, debug, output });
|
||||
const [domainName] = args;
|
||||
let contextName = null;
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import chalk from 'chalk';
|
||||
|
||||
import { NowContext } from '../../types';
|
||||
import { Output } from '../../util/output';
|
||||
import * as ERRORS from '../../util/errors-ts';
|
||||
import Client from '../../util/client';
|
||||
import getScope from '../../util/get-scope';
|
||||
@@ -24,17 +23,17 @@ type Options = {
|
||||
export default async function transferIn(
|
||||
ctx: NowContext,
|
||||
opts: Options,
|
||||
args: string[],
|
||||
output: Output
|
||||
args: string[]
|
||||
) {
|
||||
const {
|
||||
authConfig: { token },
|
||||
output,
|
||||
config,
|
||||
} = ctx;
|
||||
const { currentTeam } = config;
|
||||
const { apiUrl } = ctx;
|
||||
const debug = opts['--debug'];
|
||||
const client = new Client({ apiUrl, token, currentTeam, debug });
|
||||
const client = new Client({ apiUrl, token, currentTeam, debug, output });
|
||||
let contextName = null;
|
||||
|
||||
try {
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
import { NowContext } from '../../types';
|
||||
import { Output } from '../../util/output';
|
||||
import { NowBuildError } from '@vercel/build-utils';
|
||||
import { getCommandName } from '../../util/pkg-name';
|
||||
|
||||
export default async function verify(
|
||||
_ctx: NowContext,
|
||||
{ output }: NowContext,
|
||||
_opts: {},
|
||||
args: string[],
|
||||
output: Output
|
||||
args: string[]
|
||||
) {
|
||||
const [domainName] = args;
|
||||
|
||||
|
||||
12
packages/now-cli/src/commands/env/add.ts
vendored
12
packages/now-cli/src/commands/env/add.ts
vendored
@@ -122,7 +122,17 @@ export default async function add(
|
||||
const existing = new Set(
|
||||
envs.filter(r => r.key === envName).map(r => r.target)
|
||||
);
|
||||
const choices = getEnvTargetChoices().filter(c => !existing.has(c.value));
|
||||
const choices = getEnvTargetChoices().filter(c => {
|
||||
// hide Development if "Secret" is chosen
|
||||
if (
|
||||
envType === ProjectEnvType.Secret &&
|
||||
c.value === ProjectEnvTarget.Development
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return !existing.has(c.value);
|
||||
});
|
||||
|
||||
if (choices.length === 0) {
|
||||
output.error(
|
||||
|
||||
7
packages/now-cli/src/commands/env/index.ts
vendored
7
packages/now-cli/src/commands/env/index.ts
vendored
@@ -1,7 +1,6 @@
|
||||
import chalk from 'chalk';
|
||||
|
||||
import { NowContext } from '../../types';
|
||||
import createOutput from '../../util/output';
|
||||
import getArgs from '../../util/get-args';
|
||||
import getSubcommand from '../../util/get-subcommand';
|
||||
import getInvalidSubcommand from '../../util/get-invalid-subcommand';
|
||||
@@ -109,15 +108,15 @@ export default async function main(ctx: NowContext) {
|
||||
}
|
||||
|
||||
const debug = argv['--debug'];
|
||||
const output = createOutput({ debug });
|
||||
const { subcommand, args } = getSubcommand(argv._.slice(1), COMMAND_CONFIG);
|
||||
const {
|
||||
authConfig: { token },
|
||||
apiUrl,
|
||||
output,
|
||||
config,
|
||||
} = ctx;
|
||||
const { currentTeam } = config;
|
||||
const { apiUrl } = ctx;
|
||||
const client = new Client({ apiUrl, token, currentTeam, debug });
|
||||
const client = new Client({ apiUrl, token, currentTeam, debug, output });
|
||||
const link = await getLinkedProject(output, client);
|
||||
if (link.status === 'error') {
|
||||
return link.exitCode;
|
||||
|
||||
@@ -4,7 +4,6 @@ import getArgs from '../../util/get-args';
|
||||
import getSubcommand from '../../util/get-subcommand';
|
||||
import { NowContext } from '../../types';
|
||||
import handleError from '../../util/handle-error';
|
||||
import createOutput from '../../util/output/create-output';
|
||||
import logo from '../../util/output/logo';
|
||||
import error from '../../util/output/error';
|
||||
import init from './init';
|
||||
@@ -47,7 +46,6 @@ const help = () => {
|
||||
export default async function main(ctx: NowContext) {
|
||||
let argv;
|
||||
let args;
|
||||
let output;
|
||||
|
||||
try {
|
||||
argv = getArgs(ctx.argv.slice(2), {
|
||||
@@ -55,7 +53,6 @@ export default async function main(ctx: NowContext) {
|
||||
'-f': Boolean,
|
||||
});
|
||||
args = getSubcommand(argv._.slice(1), COMMAND_CONFIG).args;
|
||||
output = createOutput({ debug: argv['--debug'] });
|
||||
} catch (err) {
|
||||
handleError(err);
|
||||
return 1;
|
||||
@@ -67,15 +64,15 @@ export default async function main(ctx: NowContext) {
|
||||
}
|
||||
|
||||
if (argv._.length > 3) {
|
||||
output.error('Too much arguments.');
|
||||
ctx.output.error('Too much arguments.');
|
||||
return 1;
|
||||
}
|
||||
|
||||
try {
|
||||
return await init(ctx, argv, args, output);
|
||||
return await init(ctx, argv, args);
|
||||
} catch (err) {
|
||||
console.log(error(err.message));
|
||||
output.debug(err.stack);
|
||||
ctx.output.debug(err.stack);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,9 +34,9 @@ const EXAMPLE_API = 'https://now-example-files.zeit.sh';
|
||||
export default async function init(
|
||||
ctx: NowContext,
|
||||
opts: Options,
|
||||
args: string[],
|
||||
output: Output
|
||||
args: string[]
|
||||
) {
|
||||
const { output } = ctx;
|
||||
const [name, dir] = args;
|
||||
const force = opts['-f'] || opts['--force'];
|
||||
|
||||
@@ -82,12 +82,12 @@ export default async function init(
|
||||
* Fetch example list json
|
||||
*/
|
||||
async function fetchExampleList(output: Output) {
|
||||
const stopSpinner = output.spinner('Fetching examples');
|
||||
output.spinner('Fetching examples');
|
||||
const url = `${EXAMPLE_API}/v2/list.json`;
|
||||
|
||||
try {
|
||||
const resp = await fetch(url);
|
||||
stopSpinner();
|
||||
output.stopSpinner();
|
||||
|
||||
if (resp.status !== 200) {
|
||||
throw new Error(`Failed fetching list.json (${resp.statusText}).`);
|
||||
@@ -95,7 +95,7 @@ async function fetchExampleList(output: Output) {
|
||||
|
||||
return (await resp.json()) as Example[];
|
||||
} catch (e) {
|
||||
stopSpinner();
|
||||
output.stopSpinner();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,13 +127,13 @@ async function extractExample(
|
||||
ver: string = 'v2'
|
||||
) {
|
||||
const folder = prepareFolder(process.cwd(), dir || name, force);
|
||||
const stopSpinner = output.spinner(`Fetching ${name}`);
|
||||
output.spinner(`Fetching ${name}`);
|
||||
|
||||
const url = `${EXAMPLE_API}/${ver}/download/${name}.tar.gz`;
|
||||
|
||||
return fetch(url)
|
||||
.then(async resp => {
|
||||
stopSpinner();
|
||||
output.stopSpinner();
|
||||
|
||||
if (resp.status !== 200) {
|
||||
throw new Error(`Could not get ${name}.tar.gz`);
|
||||
@@ -163,7 +163,7 @@ async function extractExample(
|
||||
return 0;
|
||||
})
|
||||
.catch(e => {
|
||||
stopSpinner();
|
||||
output.stopSpinner();
|
||||
throw e;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@ import getArgs from '../util/get-args';
|
||||
import buildsList from '../util/output/builds';
|
||||
import routesList from '../util/output/routes';
|
||||
import indent from '../util/output/indent';
|
||||
import createOutput from '../util/output';
|
||||
import Now from '../util';
|
||||
import logo from '../util/output/logo';
|
||||
import elapsed from '../util/output/elapsed.ts';
|
||||
@@ -59,9 +58,13 @@ export default async function main(ctx) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
const apiUrl = ctx.apiUrl;
|
||||
const {
|
||||
apiUrl,
|
||||
output,
|
||||
authConfig: { token },
|
||||
config,
|
||||
} = ctx;
|
||||
const debugEnabled = argv['--debug'];
|
||||
const output = createOutput({ debug: debugEnabled });
|
||||
const { print, log, error } = output;
|
||||
|
||||
// extract the first parameter
|
||||
@@ -73,16 +76,13 @@ export default async function main(ctx) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
const {
|
||||
authConfig: { token },
|
||||
config,
|
||||
} = ctx;
|
||||
const { currentTeam } = config;
|
||||
const client = new Client({
|
||||
apiUrl,
|
||||
token,
|
||||
currentTeam,
|
||||
debug: debugEnabled,
|
||||
output,
|
||||
});
|
||||
let contextName = null;
|
||||
|
||||
@@ -90,25 +90,30 @@ export default async function main(ctx) {
|
||||
({ contextName } = await getScope(client));
|
||||
} catch (err) {
|
||||
if (err.code === 'NOT_AUTHORIZED' || err.code === 'TEAM_DELETED') {
|
||||
output.error(err.message);
|
||||
error(err.message);
|
||||
return 1;
|
||||
}
|
||||
|
||||
throw err;
|
||||
}
|
||||
|
||||
const now = new Now({ apiUrl, token, debug: debugEnabled, currentTeam });
|
||||
const now = new Now({
|
||||
apiUrl,
|
||||
token,
|
||||
debug: debugEnabled,
|
||||
currentTeam,
|
||||
output,
|
||||
});
|
||||
|
||||
// resolve the deployment, since we might have been given an alias
|
||||
const depFetchStart = Date.now();
|
||||
const cancelWait = output.spinner(
|
||||
output.spinner(
|
||||
`Fetching deployment "${deploymentIdOrHost}" in ${chalk.bold(contextName)}`
|
||||
);
|
||||
|
||||
try {
|
||||
deployment = await now.findDeployment(deploymentIdOrHost);
|
||||
} catch (err) {
|
||||
cancelWait();
|
||||
if (err.status === 404) {
|
||||
error(
|
||||
`Failed to find deployment "${deploymentIdOrHost}" in ${chalk.bold(
|
||||
@@ -136,7 +141,6 @@ export default async function main(ctx) {
|
||||
? await now.fetch(`/v1/now/deployments/${id}/builds`)
|
||||
: { builds: [] };
|
||||
|
||||
cancelWait();
|
||||
log(
|
||||
`Fetched deployment "${url}" in ${chalk.bold(contextName)} ${elapsed(
|
||||
Date.now() - depFetchStart
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import chalk from 'chalk';
|
||||
import { NowContext } from '../../types';
|
||||
import createOutput from '../../util/output';
|
||||
import getArgs from '../../util/get-args';
|
||||
import getSubcommand from '../../util/get-subcommand';
|
||||
import handleError from '../../util/handle-error';
|
||||
@@ -66,8 +65,6 @@ export default async function main(ctx: NowContext) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
const debug = argv['--debug'];
|
||||
const output = createOutput({ debug });
|
||||
const { args } = getSubcommand(argv._.slice(1), COMMAND_CONFIG);
|
||||
const path = args[0] || process.cwd();
|
||||
const autoConfirm = argv['--confirm'];
|
||||
@@ -75,7 +72,6 @@ export default async function main(ctx: NowContext) {
|
||||
|
||||
const link = await setupAndLink(
|
||||
ctx,
|
||||
output,
|
||||
path,
|
||||
forceDelete,
|
||||
autoConfirm,
|
||||
|
||||
@@ -3,12 +3,10 @@ import ms from 'ms';
|
||||
import table from 'text-table';
|
||||
import Now from '../util';
|
||||
import getArgs from '../util/get-args';
|
||||
import createOutput from '../util/output';
|
||||
import { handleError } from '../util/error';
|
||||
import cmd from '../util/output/cmd.ts';
|
||||
import logo from '../util/output/logo';
|
||||
import elapsed from '../util/output/elapsed.ts';
|
||||
import wait from '../util/output/wait';
|
||||
import strlen from '../util/strlen.ts';
|
||||
import Client from '../util/client.ts';
|
||||
import getScope from '../util/get-scope.ts';
|
||||
@@ -78,11 +76,15 @@ export default async function main(ctx) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
const debugEnabled = argv['--debug'];
|
||||
const {
|
||||
authConfig: { token },
|
||||
output,
|
||||
apiUrl,
|
||||
config,
|
||||
} = ctx;
|
||||
|
||||
const { print, log, error, note, debug } = createOutput({
|
||||
debug: debugEnabled,
|
||||
});
|
||||
const debugEnabled = argv['--debug'];
|
||||
const { print, log, error, note, debug, spinner } = output;
|
||||
|
||||
if (argv._.length > 2) {
|
||||
error(`${getCommandName('ls [app]')} accepts at most one argument`);
|
||||
@@ -92,24 +94,19 @@ export default async function main(ctx) {
|
||||
let app = argv._[1];
|
||||
let host = null;
|
||||
|
||||
const apiUrl = ctx.apiUrl;
|
||||
|
||||
if (argv['--help']) {
|
||||
help();
|
||||
return 0;
|
||||
}
|
||||
|
||||
const meta = parseMeta(argv['--meta']);
|
||||
const {
|
||||
authConfig: { token },
|
||||
config,
|
||||
} = ctx;
|
||||
const { currentTeam, includeScheme } = config;
|
||||
const client = new Client({
|
||||
apiUrl,
|
||||
token,
|
||||
currentTeam,
|
||||
debug: debugEnabled,
|
||||
output,
|
||||
});
|
||||
let contextName = null;
|
||||
|
||||
@@ -131,11 +128,15 @@ export default async function main(ctx) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
const stopSpinner = wait(
|
||||
`Fetching deployments in ${chalk.bold(contextName)}`
|
||||
);
|
||||
spinner(`Fetching deployments in ${chalk.bold(contextName)}`);
|
||||
|
||||
const now = new Now({ apiUrl, token, debug: debugEnabled, currentTeam });
|
||||
const now = new Now({
|
||||
apiUrl,
|
||||
token,
|
||||
debug: debugEnabled,
|
||||
output,
|
||||
currentTeam,
|
||||
});
|
||||
const start = new Date();
|
||||
|
||||
if (app && !isValidName(app)) {
|
||||
@@ -156,7 +157,6 @@ export default async function main(ctx) {
|
||||
const hostParts = asHost.split('-');
|
||||
|
||||
if (hostParts < 2) {
|
||||
stopSpinner();
|
||||
error('Only deployment hostnames are allowed, no aliases');
|
||||
return 1;
|
||||
}
|
||||
@@ -165,19 +165,12 @@ export default async function main(ctx) {
|
||||
host = asHost;
|
||||
}
|
||||
|
||||
let response;
|
||||
|
||||
try {
|
||||
debug('Fetching deployments');
|
||||
response = await now.list(app, {
|
||||
version: 6,
|
||||
meta,
|
||||
nextTimestamp,
|
||||
});
|
||||
} catch (err) {
|
||||
stopSpinner();
|
||||
throw err;
|
||||
}
|
||||
debug('Fetching deployments');
|
||||
const response = await now.list(app, {
|
||||
version: 6,
|
||||
meta,
|
||||
nextTimestamp,
|
||||
});
|
||||
|
||||
let { deployments, pagination } = response;
|
||||
|
||||
@@ -193,7 +186,6 @@ export default async function main(ctx) {
|
||||
if (err.status === 404) {
|
||||
debug('Ignore findDeployment 404');
|
||||
} else {
|
||||
stopSpinner();
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
@@ -210,7 +202,6 @@ export default async function main(ctx) {
|
||||
deployments = deployments.filter(deployment => deployment.url === host);
|
||||
}
|
||||
|
||||
stopSpinner();
|
||||
log(
|
||||
`Deployments under ${chalk.bold(contextName)} ${elapsed(
|
||||
Date.now() - start
|
||||
|
||||
@@ -19,7 +19,6 @@ import getGlobalPathConfig from '../util/config/global-path';
|
||||
import hp from '../util/humanize-path';
|
||||
import logo from '../util/output/logo';
|
||||
import exit from '../util/exit';
|
||||
import createOutput from '../util/output';
|
||||
import executeLogin from '../util/login/login.ts';
|
||||
import { prependEmoji, emoji } from '../util/emoji';
|
||||
import { getCommandName, getPkgName } from '../util/pkg-name.ts';
|
||||
@@ -141,15 +140,12 @@ const login = async ctx => {
|
||||
await exit(0);
|
||||
}
|
||||
|
||||
const debugEnabled = argv['--debug'];
|
||||
const output = createOutput({ debug: debugEnabled });
|
||||
const { apiUrl, output } = ctx;
|
||||
|
||||
argv._ = argv._.slice(1);
|
||||
|
||||
const apiUrl = ctx.apiUrl;
|
||||
let email;
|
||||
let emailIsValid = false;
|
||||
let stopSpinner;
|
||||
|
||||
const possibleAddress = argv._[0];
|
||||
|
||||
@@ -190,19 +186,18 @@ const login = async ctx => {
|
||||
let verificationToken;
|
||||
let securityCode;
|
||||
|
||||
stopSpinner = output.spinner('Sending you an email');
|
||||
output.spinner('Sending you an email');
|
||||
|
||||
try {
|
||||
const data = await executeLogin(apiUrl, email);
|
||||
verificationToken = data.token;
|
||||
securityCode = data.securityCode;
|
||||
} catch (err) {
|
||||
stopSpinner();
|
||||
console.log(error(err.message));
|
||||
output.error(err.message);
|
||||
return 1;
|
||||
}
|
||||
|
||||
stopSpinner();
|
||||
output.stopSpinner();
|
||||
|
||||
// Clear up `Sending email` success message
|
||||
process.stdout.write(eraseLines(possibleAddress ? 1 : 2));
|
||||
@@ -215,7 +210,7 @@ const login = async ctx => {
|
||||
)}.\n`
|
||||
);
|
||||
|
||||
stopSpinner = output.spinner('Waiting for your confirmation');
|
||||
output.spinner('Waiting for your confirmation');
|
||||
|
||||
let token;
|
||||
|
||||
@@ -228,14 +223,13 @@ const login = async ctx => {
|
||||
// /now/registraton is currently returning plain text in that case
|
||||
// we just wait for the user to click on the link
|
||||
} else {
|
||||
stopSpinner();
|
||||
console.log(err.message);
|
||||
output.error(err.message);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stopSpinner();
|
||||
output.stopSpinner();
|
||||
console.log(ok('Email confirmed'));
|
||||
|
||||
// There's no need to save the user since we always
|
||||
|
||||
@@ -11,7 +11,7 @@ import {
|
||||
} from '../util/config/files';
|
||||
import getArgs from '../util/get-args';
|
||||
import { NowContext } from '../types';
|
||||
import createOutput, { Output } from '../util/output';
|
||||
import { Output } from '../util/output';
|
||||
import { getPkgName } from '../util/pkg-name';
|
||||
|
||||
const help = () => {
|
||||
@@ -54,13 +54,11 @@ export default async function main(ctx: NowContext): Promise<number> {
|
||||
return 2;
|
||||
}
|
||||
|
||||
const debugEnabled = argv['--debug'];
|
||||
const output = createOutput({ debug: debugEnabled });
|
||||
return logout(ctx.apiUrl, output);
|
||||
return logout(ctx.apiUrl, ctx.output);
|
||||
}
|
||||
|
||||
const logout = async (apiUrl: string, output: Output) => {
|
||||
const spinner = output.spinner('Logging out...', 200);
|
||||
output.spinner('Logging out…', 200);
|
||||
|
||||
const configContent = readConfigFile();
|
||||
const authContent = readAuthConfigFile();
|
||||
@@ -83,7 +81,6 @@ const logout = async (apiUrl: string, output: Output) => {
|
||||
writeToAuthConfigFile(authContent);
|
||||
output.debug('Configuration has been deleted');
|
||||
} catch (err) {
|
||||
spinner();
|
||||
output.error(`Couldn't remove config while logging out`);
|
||||
return 1;
|
||||
}
|
||||
@@ -98,14 +95,12 @@ const logout = async (apiUrl: string, output: Output) => {
|
||||
if (res.status === 403) {
|
||||
output.debug('Token is invalid so it cannot be revoked');
|
||||
} else if (res.status !== 200) {
|
||||
spinner();
|
||||
const err = await res.json();
|
||||
output.error('Failed to revoke token');
|
||||
output.debug(err ? err.message : '');
|
||||
return 1;
|
||||
}
|
||||
|
||||
spinner();
|
||||
output.log('Logged out!');
|
||||
return 0;
|
||||
};
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import mri from 'mri';
|
||||
import chalk from 'chalk';
|
||||
import Now from '../util';
|
||||
import createOutput from '../util/output';
|
||||
import logo from '../util/output/logo';
|
||||
import elapsed from '../util/output/elapsed.ts';
|
||||
import { maybeURL, normalizeURL } from '../util/url';
|
||||
@@ -59,7 +58,6 @@ export default async function main(ctx) {
|
||||
let deploymentIdOrURL;
|
||||
|
||||
let debug;
|
||||
let apiUrl;
|
||||
let head;
|
||||
let limit;
|
||||
let follow;
|
||||
@@ -87,8 +85,12 @@ export default async function main(ctx) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
const debugEnabled = argv.debug;
|
||||
const output = createOutput({ debug: debugEnabled });
|
||||
const {
|
||||
authConfig: { token },
|
||||
apiUrl,
|
||||
output,
|
||||
config,
|
||||
} = ctx;
|
||||
|
||||
try {
|
||||
since = argv.since ? toTimestamp(argv.since) : 0;
|
||||
@@ -117,7 +119,6 @@ export default async function main(ctx) {
|
||||
}
|
||||
|
||||
debug = argv.debug;
|
||||
apiUrl = ctx.apiUrl;
|
||||
|
||||
head = argv.head;
|
||||
limit = typeof argv.n === 'number' ? argv.n : 100;
|
||||
@@ -125,17 +126,14 @@ export default async function main(ctx) {
|
||||
if (follow) until = 0;
|
||||
outputMode = argv.output in logPrinters ? argv.output : 'short';
|
||||
|
||||
const {
|
||||
authConfig: { token },
|
||||
config,
|
||||
} = ctx;
|
||||
const { currentTeam } = config;
|
||||
const now = new Now({ apiUrl, token, debug, currentTeam });
|
||||
const now = new Now({ apiUrl, token, debug, currentTeam, output });
|
||||
const client = new Client({
|
||||
apiUrl,
|
||||
token,
|
||||
currentTeam,
|
||||
debug: debugEnabled,
|
||||
debug,
|
||||
output,
|
||||
});
|
||||
let contextName = null;
|
||||
|
||||
@@ -154,14 +152,12 @@ export default async function main(ctx) {
|
||||
const id = deploymentIdOrURL;
|
||||
|
||||
const depFetchStart = Date.now();
|
||||
const cancelWait = output.spinner(
|
||||
`Fetching deployment "${id}" in ${chalk.bold(contextName)}`
|
||||
);
|
||||
output.spinner(`Fetching deployment "${id}" in ${chalk.bold(contextName)}`);
|
||||
|
||||
try {
|
||||
deployment = await now.findDeployment(id);
|
||||
} catch (err) {
|
||||
cancelWait();
|
||||
output.stopSpinner();
|
||||
now.close();
|
||||
|
||||
if (err.status === 404) {
|
||||
@@ -182,7 +178,6 @@ export default async function main(ctx) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
cancelWait();
|
||||
output.log(
|
||||
`Fetched deployment "${deployment.url}" in ${chalk.bold(
|
||||
contextName
|
||||
@@ -206,6 +201,7 @@ export default async function main(ctx) {
|
||||
quiet: false,
|
||||
debug,
|
||||
findOpts: findOpts1,
|
||||
output,
|
||||
});
|
||||
|
||||
const printedEventIds = new Set();
|
||||
@@ -232,6 +228,7 @@ export default async function main(ctx) {
|
||||
quiet: false,
|
||||
debug,
|
||||
findOpts: findOpts2,
|
||||
output,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ import exit from '../util/exit';
|
||||
import Client from '../util/client.ts';
|
||||
import logo from '../util/output/logo';
|
||||
import getScope from '../util/get-scope';
|
||||
import createOutput from '../util/output';
|
||||
import getCommandFlags from '../util/get-command-flags';
|
||||
import wait from '../util/output/wait';
|
||||
import { getPkgName, getCommandName } from '../util/pkg-name.ts';
|
||||
@@ -76,13 +75,12 @@ const main = async ctx => {
|
||||
return exit(2);
|
||||
}
|
||||
|
||||
const output = createOutput({ debug });
|
||||
|
||||
const {
|
||||
authConfig: { token },
|
||||
config: { currentTeam },
|
||||
output,
|
||||
} = ctx;
|
||||
const client = new Client({ apiUrl, token, currentTeam, debug });
|
||||
const client = new Client({ apiUrl, token, currentTeam, debug, output });
|
||||
|
||||
let contextName = null;
|
||||
|
||||
@@ -288,12 +286,7 @@ function readConfirmation(projectName) {
|
||||
process.stdin
|
||||
.on('data', d => {
|
||||
process.stdin.pause();
|
||||
resolve(
|
||||
d
|
||||
.toString()
|
||||
.trim()
|
||||
.toLowerCase() === 'y'
|
||||
);
|
||||
resolve(d.toString().trim().toLowerCase() === 'y');
|
||||
})
|
||||
.resume();
|
||||
});
|
||||
|
||||
@@ -5,7 +5,6 @@ import plural from 'pluralize';
|
||||
import table from 'text-table';
|
||||
import Now from '../util';
|
||||
import getAliases from '../util/alias/get-aliases';
|
||||
import createOutput from '../util/output';
|
||||
import logo from '../util/output/logo';
|
||||
import elapsed from '../util/output/elapsed.ts';
|
||||
import { normalizeURL } from '../util/url';
|
||||
@@ -79,12 +78,16 @@ export default async function main(ctx) {
|
||||
|
||||
argv._ = argv._.slice(1);
|
||||
|
||||
const apiUrl = ctx.apiUrl;
|
||||
const {
|
||||
apiUrl,
|
||||
authConfig: { token },
|
||||
output,
|
||||
config,
|
||||
} = ctx;
|
||||
const hard = argv.hard || false;
|
||||
const skipConfirmation = argv.yes || false;
|
||||
const ids = argv._;
|
||||
const debugEnabled = argv.debug;
|
||||
const output = createOutput({ debug: debugEnabled });
|
||||
const { success, error, log } = output;
|
||||
|
||||
if (argv.help || ids[0] === 'help') {
|
||||
@@ -107,16 +110,13 @@ export default async function main(ctx) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
const {
|
||||
authConfig: { token },
|
||||
config,
|
||||
} = ctx;
|
||||
const { currentTeam } = config;
|
||||
const client = new Client({
|
||||
apiUrl,
|
||||
token,
|
||||
currentTeam,
|
||||
debug: debugEnabled,
|
||||
output,
|
||||
});
|
||||
let contextName = null;
|
||||
|
||||
@@ -133,7 +133,7 @@ export default async function main(ctx) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
const cancelWait = output.spinner(
|
||||
output.spinner(
|
||||
`Fetching deployment(s) ${ids
|
||||
.map(id => `"${id}"`)
|
||||
.join(' ')} in ${chalk.bold(contextName)}`
|
||||
@@ -198,7 +198,7 @@ export default async function main(ctx) {
|
||||
})
|
||||
);
|
||||
} finally {
|
||||
cancelWait();
|
||||
output.stopSpinner();
|
||||
}
|
||||
|
||||
deployments = deployments.filter((match, i) => {
|
||||
@@ -235,11 +235,9 @@ export default async function main(ctx) {
|
||||
}
|
||||
|
||||
if (!skipConfirmation) {
|
||||
const confirmation = (await readConfirmation(
|
||||
deployments,
|
||||
projects,
|
||||
output
|
||||
)).toLowerCase();
|
||||
const confirmation = (
|
||||
await readConfirmation(deployments, projects, output)
|
||||
).toLowerCase();
|
||||
|
||||
if (confirmation !== 'y' && confirmation !== 'yes') {
|
||||
output.log('Aborted');
|
||||
@@ -248,7 +246,13 @@ export default async function main(ctx) {
|
||||
}
|
||||
}
|
||||
|
||||
const now = new Now({ apiUrl, token, debug: debugEnabled, currentTeam });
|
||||
const now = new Now({
|
||||
apiUrl,
|
||||
token,
|
||||
debug: debugEnabled,
|
||||
currentTeam,
|
||||
output,
|
||||
});
|
||||
const start = new Date();
|
||||
|
||||
await Promise.all([
|
||||
|
||||
@@ -9,7 +9,6 @@ import exit from '../util/exit';
|
||||
import logo from '../util/output/logo';
|
||||
import Client from '../util/client.ts';
|
||||
import getScope from '../util/get-scope.ts';
|
||||
import createOutput from '../util/output';
|
||||
import confirm from '../util/input/confirm';
|
||||
import getCommandFlags from '../util/get-command-flags';
|
||||
import getPrefixedFlags from '../util/get-prefixed-flags';
|
||||
@@ -104,10 +103,10 @@ const main = async ctx => {
|
||||
|
||||
const {
|
||||
authConfig: { token },
|
||||
output,
|
||||
config: { currentTeam },
|
||||
} = ctx;
|
||||
const output = createOutput({ debug });
|
||||
const client = new Client({ apiUrl, token, currentTeam, debug });
|
||||
const client = new Client({ apiUrl, token, currentTeam, debug, output });
|
||||
let contextName = null;
|
||||
|
||||
try {
|
||||
@@ -139,7 +138,7 @@ export default async ctx => {
|
||||
};
|
||||
|
||||
async function run({ output, token, contextName, currentTeam, ctx }) {
|
||||
const secrets = new NowSecrets({ apiUrl, token, debug, currentTeam });
|
||||
const secrets = new NowSecrets({ apiUrl, token, debug, currentTeam, output });
|
||||
const args = argv._.slice(1);
|
||||
const start = Date.now();
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ const help = () => {
|
||||
${chalk.gray('–')} Invite new members (interactively)
|
||||
|
||||
${chalk.cyan(`$ ${getPkgName()} teams invite`)}
|
||||
|
||||
|
||||
${chalk.gray('–')} Paginate results, where ${chalk.dim(
|
||||
'`1584722256178`'
|
||||
)} is the time in milliseconds since the UNIX epoch.
|
||||
@@ -97,10 +97,11 @@ const main = async ctx => {
|
||||
|
||||
const {
|
||||
authConfig: { token },
|
||||
output,
|
||||
config,
|
||||
} = ctx;
|
||||
|
||||
return run({ token, config });
|
||||
return run({ token, config, output });
|
||||
};
|
||||
|
||||
export default async ctx => {
|
||||
@@ -112,7 +113,7 @@ export default async ctx => {
|
||||
}
|
||||
};
|
||||
|
||||
async function run({ token, config }) {
|
||||
async function run({ token, config, output }) {
|
||||
const { currentTeam } = config;
|
||||
const teams = new NowTeams({ apiUrl, token, debug, currentTeam });
|
||||
const args = argv._;
|
||||
@@ -126,6 +127,7 @@ async function run({ token, config }) {
|
||||
config,
|
||||
apiUrl,
|
||||
token,
|
||||
output,
|
||||
argv,
|
||||
});
|
||||
break;
|
||||
@@ -138,6 +140,7 @@ async function run({ token, config }) {
|
||||
apiUrl,
|
||||
token,
|
||||
debug,
|
||||
output,
|
||||
});
|
||||
break;
|
||||
}
|
||||
@@ -154,6 +157,7 @@ async function run({ token, config }) {
|
||||
config,
|
||||
apiUrl,
|
||||
token,
|
||||
output,
|
||||
});
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ import success from '../../util/output/success';
|
||||
import getUser from '../../util/get-user.ts';
|
||||
import Client from '../../util/client.ts';
|
||||
import { getCommandName } from '../../util/pkg-name.ts';
|
||||
import createOutput from '../../util/output';
|
||||
|
||||
const validateEmail = data => regexEmail.test(data.trim()) || data.length === 0;
|
||||
|
||||
@@ -65,8 +64,8 @@ export default async function ({
|
||||
noopMsg = 'No changes made',
|
||||
apiUrl,
|
||||
token,
|
||||
output,
|
||||
} = {}) {
|
||||
const output = createOutput();
|
||||
const { currentTeam: currentTeamId } = config;
|
||||
|
||||
const stopSpinner = wait('Fetching teams');
|
||||
@@ -77,7 +76,7 @@ export default async function ({
|
||||
stopSpinner();
|
||||
|
||||
const stopUserSpinner = wait('Fetching user information');
|
||||
const client = new Client({ apiUrl, token });
|
||||
const client = new Client({ apiUrl, token, output });
|
||||
let user;
|
||||
try {
|
||||
user = await getUser(client);
|
||||
|
||||
@@ -8,7 +8,6 @@ import info from '../../util/output/info';
|
||||
import error from '../../util/output/error';
|
||||
import chars from '../../util/output/chars';
|
||||
import table from '../../util/output/table';
|
||||
import createOutput from '../../util/output';
|
||||
import getUser from '../../util/get-user.ts';
|
||||
import Client from '../../util/client.ts';
|
||||
import getPrefixedFlags from '../../util/get-prefixed-flags';
|
||||
@@ -16,9 +15,8 @@ import { getPkgName } from '../../util/pkg-name.ts';
|
||||
import getCommandFlags from '../../util/get-command-flags';
|
||||
import cmd from '../../util/output/cmd.ts';
|
||||
|
||||
export default async function({ teams, config, apiUrl, token, argv }) {
|
||||
export default async function ({ teams, config, apiUrl, token, output, argv }) {
|
||||
const { next } = argv;
|
||||
const output = createOutput({ debug: argv['--debug'] });
|
||||
|
||||
if (typeof next !== 'undefined' && !Number.isInteger(next)) {
|
||||
output.error('Please provide a number for flag --next');
|
||||
@@ -36,7 +34,7 @@ export default async function({ teams, config, apiUrl, token, argv }) {
|
||||
stopSpinner();
|
||||
|
||||
const stopUserSpinner = wait('Fetching user information');
|
||||
const client = new Client({ apiUrl, token, currentTeam });
|
||||
const client = new Client({ apiUrl, token, currentTeam, output });
|
||||
let user;
|
||||
try {
|
||||
user = await getUser(client);
|
||||
|
||||
@@ -2,8 +2,6 @@
|
||||
import chalk from 'chalk';
|
||||
|
||||
// Utilities
|
||||
import wait from '../../util/output/wait';
|
||||
|
||||
import listInput from '../../util/input/list';
|
||||
import success from '../../util/output/success';
|
||||
import info from '../../util/output/info';
|
||||
@@ -24,22 +22,20 @@ const updateCurrentTeam = (config, newTeam) => {
|
||||
writeToConfigFile(config);
|
||||
};
|
||||
|
||||
export default async function({ apiUrl, token, debug, args, config }) {
|
||||
let stopSpinner = wait('Fetching teams');
|
||||
export default async function ({ apiUrl, token, debug, args, config, output }) {
|
||||
output.spinner('Fetching teams');
|
||||
|
||||
// We're loading the teams here without `currentTeam`, so that
|
||||
// people can use `vercel switch` in the case that their
|
||||
// current team was deleted.
|
||||
const teams = new NowTeams({ apiUrl, token, debug });
|
||||
const teams = new NowTeams({ apiUrl, token, debug, output });
|
||||
const list = (await teams.ls()).teams;
|
||||
|
||||
let { currentTeam } = config;
|
||||
const accountIsCurrent = !currentTeam;
|
||||
|
||||
stopSpinner();
|
||||
|
||||
const stopUserSpinner = wait('Fetching user information');
|
||||
const client = new Client({ apiUrl, token });
|
||||
output.spinner('Fetching user information');
|
||||
const client = new Client({ apiUrl, token, output });
|
||||
let user;
|
||||
try {
|
||||
user = await getUser(client);
|
||||
@@ -52,8 +48,6 @@ export default async function({ apiUrl, token, debug, args, config }) {
|
||||
throw err;
|
||||
}
|
||||
|
||||
stopUserSpinner();
|
||||
|
||||
if (accountIsCurrent) {
|
||||
currentTeam = {
|
||||
slug: user.username || user.email,
|
||||
@@ -84,10 +78,10 @@ export default async function({ apiUrl, token, debug, args, config }) {
|
||||
}
|
||||
|
||||
if (desiredSlug === user.username) {
|
||||
stopSpinner = wait('Saving');
|
||||
output.spinner('Saving');
|
||||
updateCurrentTeam(config);
|
||||
|
||||
stopSpinner();
|
||||
output.stopSpinner();
|
||||
console.log(
|
||||
success(`Your account (${chalk.bold(desiredSlug)}) is now active!`)
|
||||
);
|
||||
@@ -163,10 +157,10 @@ export default async function({ apiUrl, token, debug, args, config }) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
stopSpinner = wait('Saving');
|
||||
output.spinner('Saving');
|
||||
updateCurrentTeam(config);
|
||||
|
||||
stopSpinner();
|
||||
output.stopSpinner();
|
||||
console.log(success(`Your account (${chalk.bold(choice)}) is now active!`));
|
||||
return 0;
|
||||
}
|
||||
@@ -176,10 +170,10 @@ export default async function({ apiUrl, token, debug, args, config }) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
stopSpinner = wait('Saving');
|
||||
output.spinner('Saving');
|
||||
updateCurrentTeam(config, newTeam);
|
||||
|
||||
stopSpinner();
|
||||
output.stopSpinner();
|
||||
console.log(
|
||||
success(
|
||||
`The team ${chalk.bold(newTeam.name)} (${newTeam.slug}) is now active!`
|
||||
|
||||
@@ -5,7 +5,6 @@ import logo from '../util/output/logo';
|
||||
import handleError from '../util/handle-error';
|
||||
import getArgs from '../util/get-args';
|
||||
import { NowContext } from '../types';
|
||||
import createOutput from '../util/output';
|
||||
import getUpdateCommand from '../util/get-update-command';
|
||||
import { getPkgName, getTitleName } from '../util/pkg-name';
|
||||
|
||||
@@ -35,6 +34,7 @@ const help = () => {
|
||||
|
||||
export default async function main(ctx: NowContext): Promise<number> {
|
||||
let argv;
|
||||
const { output } = ctx;
|
||||
|
||||
try {
|
||||
argv = getArgs(ctx.argv.slice(2), {
|
||||
@@ -55,8 +55,6 @@ export default async function main(ctx: NowContext): Promise<number> {
|
||||
return 2;
|
||||
}
|
||||
|
||||
const debugEnabled = argv['--debug'];
|
||||
const output = createOutput({ debug: debugEnabled });
|
||||
output.log(
|
||||
`Please run ${cmd(
|
||||
await getUpdateCommand()
|
||||
|
||||
@@ -4,7 +4,6 @@ import logo from '../util/output/logo';
|
||||
import { handleError } from '../util/error';
|
||||
import Client from '../util/client.ts';
|
||||
import getScope from '../util/get-scope.ts';
|
||||
import createOutput from '../util/output';
|
||||
import { getPkgName } from '../util/pkg-name.ts';
|
||||
|
||||
const help = () => {
|
||||
@@ -55,10 +54,10 @@ const main = async ctx => {
|
||||
const debug = argv['--debug'];
|
||||
const {
|
||||
authConfig: { token },
|
||||
output,
|
||||
apiUrl,
|
||||
} = ctx;
|
||||
const output = createOutput({ debug });
|
||||
const client = new Client({ apiUrl, token, debug });
|
||||
const client = new Client({ apiUrl, token, debug, output });
|
||||
let contextName = null;
|
||||
|
||||
try {
|
||||
|
||||
@@ -291,7 +291,7 @@ const main = async argv_ => {
|
||||
|
||||
let authConfig = null;
|
||||
|
||||
const subcommandsWithoutToken = ['login', 'help', 'init', 'dev', 'update'];
|
||||
const subcommandsWithoutToken = ['login', 'help', 'init', 'update'];
|
||||
|
||||
if (authConfigExists) {
|
||||
try {
|
||||
@@ -346,6 +346,7 @@ const main = async argv_ => {
|
||||
|
||||
// the context object to supply to the providers or the commands
|
||||
const ctx = {
|
||||
output,
|
||||
config,
|
||||
authConfig,
|
||||
localConfig,
|
||||
@@ -536,7 +537,7 @@ const main = async argv_ => {
|
||||
!(targetCommand === 'teams' && argv._[3] !== 'invite')
|
||||
) {
|
||||
let user = null;
|
||||
const client = new Client({ apiUrl, token });
|
||||
const client = new Client({ apiUrl, token, output });
|
||||
|
||||
try {
|
||||
user = await getUser(client);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { NowConfig } from './util/dev/types';
|
||||
import { Output } from './util/output';
|
||||
|
||||
export type ThenArg<T> = T extends Promise<infer U> ? U : T;
|
||||
|
||||
@@ -8,6 +9,7 @@ export interface NowContext {
|
||||
authConfig: {
|
||||
token: string;
|
||||
};
|
||||
output: Output;
|
||||
config: {
|
||||
currentTeam: string;
|
||||
updateChannel: string;
|
||||
|
||||
@@ -19,14 +19,14 @@ export default async function createAlias(
|
||||
alias: string,
|
||||
externalDomain: boolean
|
||||
) {
|
||||
let cancelMessage = output.spinner(`Creating alias`);
|
||||
output.spinner(`Creating alias`);
|
||||
const result = await performCreateAlias(
|
||||
client,
|
||||
contextName,
|
||||
deployment,
|
||||
alias
|
||||
);
|
||||
cancelMessage();
|
||||
output.stopSpinner();
|
||||
|
||||
if (result instanceof ERRORS.CertMissing) {
|
||||
const cert = await createCertForAlias(
|
||||
@@ -40,14 +40,14 @@ export default async function createAlias(
|
||||
return cert;
|
||||
}
|
||||
|
||||
let cancelMessage = output.spinner(`Creating alias`);
|
||||
output.spinner(`Creating alias`);
|
||||
const secondTry = await performCreateAlias(
|
||||
client,
|
||||
contextName,
|
||||
deployment,
|
||||
alias
|
||||
);
|
||||
cancelMessage();
|
||||
output.stopSpinner();
|
||||
return secondTry;
|
||||
}
|
||||
|
||||
|
||||
@@ -37,9 +37,7 @@ export async function getDeploymentForAlias(
|
||||
contextName: string,
|
||||
localConfig: NowConfig
|
||||
) {
|
||||
const cancelWait = output.spinner(
|
||||
`Fetching deployment to alias in ${chalk.bold(contextName)}`
|
||||
);
|
||||
output.spinner(`Fetching deployment to alias in ${chalk.bold(contextName)}`);
|
||||
|
||||
// When there are no args at all we try to get the targets from the config
|
||||
if (args.length === 2) {
|
||||
@@ -49,7 +47,7 @@ export async function getDeploymentForAlias(
|
||||
contextName,
|
||||
deploymentId
|
||||
);
|
||||
cancelWait();
|
||||
output.stopSpinner();
|
||||
return deployment;
|
||||
}
|
||||
|
||||
@@ -68,6 +66,6 @@ export async function getDeploymentForAlias(
|
||||
user,
|
||||
contextName
|
||||
);
|
||||
cancelWait();
|
||||
output.stopSpinner();
|
||||
return deployment;
|
||||
}
|
||||
|
||||
@@ -13,20 +13,21 @@ export default async function createCertificateForAlias(
|
||||
alias: string,
|
||||
shouldBeWildcard: boolean
|
||||
) {
|
||||
output.spinner(`Generating a certificate…`);
|
||||
const cns = shouldBeWildcard ? getWildcardCnsForAlias(alias) : [alias];
|
||||
const cancelMessage = output.spinner(`Generating a certificate...`);
|
||||
const certStamp = stamp();
|
||||
const cert = await createCertForCns(client, cns, context);
|
||||
|
||||
if (cert instanceof NowError) {
|
||||
cancelMessage();
|
||||
output.stopSpinner();
|
||||
return cert;
|
||||
}
|
||||
|
||||
cancelMessage();
|
||||
output.log(
|
||||
`Certificate for ${joinWords(cert.cns)} (${
|
||||
cert.uid
|
||||
}) created ${certStamp()}`
|
||||
);
|
||||
|
||||
return cert;
|
||||
}
|
||||
|
||||
@@ -33,6 +33,7 @@ export default class Client extends EventEmitter {
|
||||
forceNew = false,
|
||||
withCache = false,
|
||||
debug = false,
|
||||
output = createOutput({ debug }),
|
||||
}: {
|
||||
apiUrl: string;
|
||||
token: string;
|
||||
@@ -40,13 +41,14 @@ export default class Client extends EventEmitter {
|
||||
forceNew?: boolean;
|
||||
withCache?: boolean;
|
||||
debug?: boolean;
|
||||
output?: Output;
|
||||
}) {
|
||||
super();
|
||||
this._token = token;
|
||||
this._debug = debug;
|
||||
this._forceNew = forceNew;
|
||||
this._withCache = withCache;
|
||||
this._output = createOutput({ debug });
|
||||
this._output = output;
|
||||
this._apiUrl = apiUrl;
|
||||
this._onRetry = this._onRetry.bind(this);
|
||||
this.currentTeam = currentTeam;
|
||||
|
||||
@@ -22,25 +22,21 @@ export default async function generateCertForDeploy(
|
||||
return new InvalidDomain(deployURL);
|
||||
}
|
||||
|
||||
const cancelSetupWait = output.spinner(
|
||||
`Setting custom suffix domain ${domain}`
|
||||
);
|
||||
output.spinner(`Setting custom suffix domain ${domain}`);
|
||||
const result = await setupDomain(output, client, domain, contextName);
|
||||
cancelSetupWait();
|
||||
output.stopSpinner();
|
||||
if (result instanceof NowError) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Generate the certificate with the given parameters
|
||||
const cancelCertWait = output.spinner(
|
||||
`Generating a wildcard certificate for ${domain}`
|
||||
);
|
||||
output.spinner(`Generating a wildcard certificate for ${domain}`);
|
||||
const cert = await createCertForCns(
|
||||
client,
|
||||
[domain, `*.${domain}`],
|
||||
contextName
|
||||
);
|
||||
cancelCertWait();
|
||||
output.stopSpinner();
|
||||
if (cert instanceof NowError) {
|
||||
return cert;
|
||||
}
|
||||
|
||||
@@ -100,11 +100,7 @@ export default async function processDeployment({
|
||||
skipAutoDetectionConfirmation,
|
||||
};
|
||||
|
||||
let queuedSpinner = null;
|
||||
let buildSpinner = null;
|
||||
let deploySpinner = null;
|
||||
|
||||
const deployingSpinner = output.spinner(
|
||||
output.spinner(
|
||||
isSettingUpProject
|
||||
? 'Setting up project'
|
||||
: `Deploying ${chalk.bold(`${org.slug}/${projectName}`)}`,
|
||||
@@ -138,16 +134,7 @@ export default async function processDeployment({
|
||||
.map((sha: string) => event.payload.total.get(sha).data.length)
|
||||
.reduce((a: number, b: number) => a + b, 0);
|
||||
|
||||
if (queuedSpinner) {
|
||||
queuedSpinner();
|
||||
}
|
||||
if (buildSpinner) {
|
||||
buildSpinner();
|
||||
}
|
||||
if (deploySpinner) {
|
||||
deploySpinner();
|
||||
}
|
||||
deployingSpinner();
|
||||
output.stopSpinner();
|
||||
bar = new Progress(`${chalk.gray('>')} Upload [:bar] :percent :etas`, {
|
||||
width: 20,
|
||||
complete: '=',
|
||||
@@ -170,8 +157,6 @@ export default async function processDeployment({
|
||||
}
|
||||
|
||||
if (event.type === 'created') {
|
||||
deployingSpinner();
|
||||
|
||||
if (bar && !bar.complete) {
|
||||
bar.tick(bar.total + 1);
|
||||
}
|
||||
@@ -191,63 +176,36 @@ export default async function processDeployment({
|
||||
|
||||
now.url = event.payload.url;
|
||||
|
||||
output.stopSpinner();
|
||||
|
||||
printInspectUrl(output, event.payload.url, deployStamp, org.slug);
|
||||
|
||||
if (quiet) {
|
||||
process.stdout.write(`https://${event.payload.url}`);
|
||||
}
|
||||
|
||||
if (queuedSpinner === null) {
|
||||
queuedSpinner =
|
||||
event.payload.readyState === 'QUEUED'
|
||||
? output.spinner('Queued', 0)
|
||||
: output.spinner('Building', 0);
|
||||
}
|
||||
output.spinner(
|
||||
event.payload.readyState === 'QUEUED' ? 'Queued' : 'Building',
|
||||
0
|
||||
);
|
||||
}
|
||||
|
||||
if (event.type === 'building') {
|
||||
if (queuedSpinner) {
|
||||
queuedSpinner();
|
||||
}
|
||||
|
||||
if (buildSpinner === null) {
|
||||
buildSpinner = output.spinner('Building', 0);
|
||||
}
|
||||
output.spinner('Building', 0);
|
||||
}
|
||||
|
||||
if (event.type === 'canceled') {
|
||||
if (queuedSpinner) {
|
||||
queuedSpinner();
|
||||
}
|
||||
if (buildSpinner) {
|
||||
buildSpinner();
|
||||
}
|
||||
output.stopSpinner();
|
||||
return event.payload;
|
||||
}
|
||||
|
||||
if (event.type === 'ready') {
|
||||
if (queuedSpinner) {
|
||||
queuedSpinner();
|
||||
}
|
||||
if (buildSpinner) {
|
||||
buildSpinner();
|
||||
}
|
||||
|
||||
deploySpinner = output.spinner('Completing', 0);
|
||||
output.spinner('Completing', 0);
|
||||
}
|
||||
|
||||
// Handle error events
|
||||
if (event.type === 'error') {
|
||||
if (queuedSpinner) {
|
||||
queuedSpinner();
|
||||
}
|
||||
if (buildSpinner) {
|
||||
buildSpinner();
|
||||
}
|
||||
if (deploySpinner) {
|
||||
deploySpinner();
|
||||
}
|
||||
deployingSpinner();
|
||||
output.stopSpinner();
|
||||
|
||||
const error = await now.handleDeploymentError(event.payload, {
|
||||
hashes,
|
||||
@@ -263,32 +221,12 @@ export default async function processDeployment({
|
||||
|
||||
// Handle alias-assigned event
|
||||
if (event.type === 'alias-assigned') {
|
||||
if (queuedSpinner) {
|
||||
queuedSpinner();
|
||||
}
|
||||
if (buildSpinner) {
|
||||
buildSpinner();
|
||||
}
|
||||
if (deploySpinner) {
|
||||
deploySpinner();
|
||||
}
|
||||
deployingSpinner();
|
||||
|
||||
event.payload.indications = indications;
|
||||
return event.payload;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
if (queuedSpinner) {
|
||||
queuedSpinner();
|
||||
}
|
||||
if (buildSpinner) {
|
||||
buildSpinner();
|
||||
}
|
||||
if (deploySpinner) {
|
||||
deploySpinner();
|
||||
}
|
||||
deployingSpinner();
|
||||
output.stopSpinner();
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -222,14 +222,14 @@ async function npmInstall(
|
||||
) {
|
||||
const sortedPackages = packagesToInstall.sort();
|
||||
|
||||
const stopSpinner = silent
|
||||
? () => {}
|
||||
: output.spinner(
|
||||
`Installing ${pluralize(
|
||||
'Runtime',
|
||||
sortedPackages.length
|
||||
)}: ${sortedPackages.join(', ')}`
|
||||
);
|
||||
if (!silent) {
|
||||
output.spinner(
|
||||
`Installing ${pluralize(
|
||||
'Runtime',
|
||||
sortedPackages.length
|
||||
)}: ${sortedPackages.join(', ')}`
|
||||
);
|
||||
}
|
||||
|
||||
output.debug(`Running npm install in ${cwd}`);
|
||||
|
||||
@@ -253,7 +253,7 @@ async function npmInstall(
|
||||
stdio: output.isDebugEnabled() ? 'inherit' : 'pipe',
|
||||
});
|
||||
if (result.failed) {
|
||||
stopSpinner();
|
||||
output.stopSpinner();
|
||||
if (result.stdout) {
|
||||
console.log(result.stdout);
|
||||
}
|
||||
@@ -272,7 +272,7 @@ async function npmInstall(
|
||||
});
|
||||
}
|
||||
} finally {
|
||||
stopSpinner();
|
||||
output.stopSpinner();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -280,7 +280,6 @@ export async function executeBuild(
|
||||
path = extensionless;
|
||||
}
|
||||
|
||||
delete output[path];
|
||||
output[path] = value;
|
||||
});
|
||||
|
||||
@@ -402,7 +401,7 @@ export async function getBuildMatches(
|
||||
const builds = nowConfig.builds || [{ src: '**', use: '@vercel/static' }];
|
||||
|
||||
for (const buildConfig of builds) {
|
||||
let { src = '**', use } = buildConfig;
|
||||
let { src = '**', use, config = {} } = buildConfig;
|
||||
|
||||
if (!use) {
|
||||
continue;
|
||||
@@ -437,6 +436,15 @@ export async function getBuildMatches(
|
||||
|
||||
for (const file of files) {
|
||||
src = relative(cwd, file);
|
||||
|
||||
// Remove the output directory prefix
|
||||
if (config.zeroConfig && config.outputDirectory) {
|
||||
const outputMatch = config.outputDirectory + '/';
|
||||
if (src.startsWith(outputMatch)) {
|
||||
src = src.slice(outputMatch.length);
|
||||
}
|
||||
}
|
||||
|
||||
const builderWithPkg = await getBuilder(use, output);
|
||||
matches.push({
|
||||
...buildConfig,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { basename, extname, join } from 'path';
|
||||
import {
|
||||
FileFsRef,
|
||||
BuildOptions,
|
||||
shouldServe as defaultShouldServe,
|
||||
ShouldServeOptions,
|
||||
} from '@vercel/build-utils';
|
||||
import { BuildResult } from './types';
|
||||
@@ -11,50 +11,32 @@ export const version = 2;
|
||||
export function build({
|
||||
files,
|
||||
entrypoint,
|
||||
config,
|
||||
config: { zeroConfig, outputDirectory },
|
||||
}: BuildOptions): BuildResult {
|
||||
let path = entrypoint;
|
||||
const outputDir = config.zeroConfig ? config.outputDirectory : '';
|
||||
const outputMatch = outputDir + '/';
|
||||
if (outputDir && path.startsWith(outputMatch)) {
|
||||
// static output files are moved to the root directory
|
||||
path = path.slice(outputMatch.length);
|
||||
}
|
||||
const output = {
|
||||
[path]: files[entrypoint] as FileFsRef,
|
||||
const path =
|
||||
zeroConfig && outputDirectory
|
||||
? `${outputDirectory}/${entrypoint}`
|
||||
: entrypoint;
|
||||
return {
|
||||
output: {
|
||||
[entrypoint]: files[path] as FileFsRef,
|
||||
},
|
||||
routes: [],
|
||||
watch: [path],
|
||||
};
|
||||
const watch = [path];
|
||||
|
||||
return { output, routes: [], watch };
|
||||
}
|
||||
|
||||
export function shouldServe({
|
||||
entrypoint,
|
||||
files,
|
||||
requestPath,
|
||||
config = {},
|
||||
}: ShouldServeOptions) {
|
||||
let outputPrefix = '';
|
||||
const outputDir = config.zeroConfig ? config.outputDirectory : '';
|
||||
const outputMatch = outputDir + '/';
|
||||
if (outputDir && entrypoint.startsWith(outputMatch)) {
|
||||
// static output files are moved to the root directory
|
||||
entrypoint = entrypoint.slice(outputMatch.length);
|
||||
outputPrefix = outputMatch;
|
||||
export function shouldServe(_opts: ShouldServeOptions) {
|
||||
const opts = { ..._opts };
|
||||
let {
|
||||
config: { zeroConfig, outputDirectory },
|
||||
} = opts;
|
||||
|
||||
// Add the output directory prefix
|
||||
if (zeroConfig && outputDirectory) {
|
||||
opts.entrypoint = `${outputDirectory}/${opts.entrypoint}`;
|
||||
opts.requestPath = `${outputDirectory}/${opts.requestPath}`;
|
||||
}
|
||||
const isMatch = (f: string) => entrypoint === f && outputPrefix + f in files;
|
||||
|
||||
if (isIndex(entrypoint)) {
|
||||
const indexPath = join(requestPath, basename(entrypoint));
|
||||
if (isMatch(indexPath)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return isMatch(requestPath);
|
||||
}
|
||||
|
||||
function isIndex(path: string): boolean {
|
||||
const ext = extname(path);
|
||||
const name = basename(path, ext);
|
||||
return name === 'index';
|
||||
return defaultShouldServe(opts);
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ export default async function purchaseDomainIfAvailable(
|
||||
domain: string,
|
||||
contextName: string
|
||||
) {
|
||||
const cancelWait = output.spinner(`Checking status of ${chalk.bold(domain)}`);
|
||||
output.spinner(`Checking status of ${chalk.bold(domain)}`);
|
||||
const buyDomainStamp = stamp();
|
||||
const { available } = await getDomainStatus(client, domain);
|
||||
|
||||
@@ -32,7 +32,7 @@ export default async function purchaseDomainIfAvailable(
|
||||
output.debug(`Domain ${domain} is available to be purchased`);
|
||||
|
||||
const domainPrice = await getDomainPrice(client, domain).finally(() => {
|
||||
cancelWait();
|
||||
output.stopSpinner();
|
||||
});
|
||||
|
||||
if (domainPrice instanceof ERRORS.UnsupportedTLD) {
|
||||
|
||||
@@ -12,11 +12,12 @@ type Response = {
|
||||
export default async function purchaseDomain(
|
||||
client: Client,
|
||||
name: string,
|
||||
expectedPrice: number
|
||||
expectedPrice: number,
|
||||
renew: boolean = true
|
||||
) {
|
||||
try {
|
||||
return await client.fetch<Response>(`/v3/domains/buy`, {
|
||||
body: { name, expectedPrice },
|
||||
body: { name, expectedPrice, renew },
|
||||
method: 'POST',
|
||||
});
|
||||
} catch (error) {
|
||||
|
||||
@@ -7,16 +7,21 @@ import { eraseLines } from 'ansi-escapes';
|
||||
import jsonlines from 'jsonlines';
|
||||
import retry from 'async-retry';
|
||||
|
||||
// Utilities
|
||||
import createOutput from './output';
|
||||
|
||||
async function printEvents(
|
||||
now,
|
||||
deploymentIdOrURL,
|
||||
currentTeam = null,
|
||||
{ mode, onOpen = () => {}, onEvent, quiet, debugEnabled, findOpts } = {}
|
||||
{
|
||||
mode,
|
||||
onOpen = () => {},
|
||||
onEvent,
|
||||
quiet,
|
||||
debugEnabled,
|
||||
findOpts,
|
||||
output,
|
||||
} = {}
|
||||
) {
|
||||
const { log, debug } = createOutput({ debug: debugEnabled });
|
||||
const { log, debug } = output;
|
||||
|
||||
let onOpenCalled = false;
|
||||
function callOnOpenOnce() {
|
||||
|
||||
@@ -23,6 +23,7 @@ export default class Now extends EventEmitter {
|
||||
forceNew = false,
|
||||
withCache = false,
|
||||
debug = false,
|
||||
output = createOutput({ debug }),
|
||||
}) {
|
||||
super();
|
||||
|
||||
@@ -30,7 +31,7 @@ export default class Now extends EventEmitter {
|
||||
this._debug = debug;
|
||||
this._forceNew = forceNew;
|
||||
this._withCache = withCache;
|
||||
this._output = createOutput({ debug });
|
||||
this._output = output;
|
||||
this._apiUrl = apiUrl;
|
||||
this._onRetry = this._onRetry.bind(this);
|
||||
this.currentTeam = currentTeam;
|
||||
|
||||
@@ -19,10 +19,7 @@ export default async function inputProject(
|
||||
|
||||
// attempt to auto-detect a project to link
|
||||
let detectedProject = null;
|
||||
const existingProjectSpinner = output.spinner(
|
||||
'Searching for existing projects…',
|
||||
1000
|
||||
);
|
||||
output.spinner('Searching for existing projects…', 1000);
|
||||
try {
|
||||
const [project, slugifiedProject] = await Promise.all([
|
||||
getProjectByIdOrName(client, detectedProjectName, org.id),
|
||||
@@ -36,7 +33,7 @@ export default async function inputProject(
|
||||
? slugifiedProject
|
||||
: null;
|
||||
} catch (error) {}
|
||||
existingProjectSpinner();
|
||||
output.stopSpinner();
|
||||
|
||||
if (autoConfirm) {
|
||||
return detectedProject || detectedProjectName;
|
||||
@@ -84,11 +81,11 @@ export default async function inputProject(
|
||||
continue;
|
||||
}
|
||||
|
||||
const spinner = output.spinner('Verifying project name…', 1000);
|
||||
output.spinner('Verifying project name…', 1000);
|
||||
try {
|
||||
project = await getProjectByIdOrName(client, projectName, org.id);
|
||||
} finally {
|
||||
spinner();
|
||||
output.stopSpinner();
|
||||
}
|
||||
|
||||
if (project instanceof ProjectNotFound) {
|
||||
@@ -116,7 +113,7 @@ export default async function inputProject(
|
||||
continue;
|
||||
}
|
||||
|
||||
const spinner = output.spinner('Verifying project name…', 1000);
|
||||
output.spinner('Verifying project name…', 1000);
|
||||
let existingProject: Project | ProjectNotFound;
|
||||
try {
|
||||
existingProject = await getProjectByIdOrName(
|
||||
@@ -125,7 +122,7 @@ export default async function inputProject(
|
||||
org.id
|
||||
);
|
||||
} finally {
|
||||
spinner();
|
||||
output.stopSpinner();
|
||||
}
|
||||
|
||||
if (existingProject && !(existingProject instanceof ProjectNotFound)) {
|
||||
|
||||
@@ -23,7 +23,7 @@ export default async function promptBool(label: string, options: Options = {}) {
|
||||
trailing = '',
|
||||
} = options;
|
||||
|
||||
return new Promise(resolve => {
|
||||
return new Promise<boolean>(resolve => {
|
||||
const isRaw = Boolean(stdin && stdin.isRaw);
|
||||
|
||||
if (stdin) {
|
||||
|
||||
@@ -16,13 +16,13 @@ export default async function selectOrg(
|
||||
): Promise<Org> {
|
||||
require('./patch-inquirer');
|
||||
|
||||
const spinner = output.spinner('Loading scopes…', 1000);
|
||||
output.spinner('Loading scopes…', 1000);
|
||||
let user: User;
|
||||
let teams: Team[];
|
||||
try {
|
||||
[user, teams] = await Promise.all([getUser(client), getTeams(client)]);
|
||||
} finally {
|
||||
spinner();
|
||||
output.stopSpinner();
|
||||
}
|
||||
|
||||
const choices: Choice[] = [
|
||||
|
||||
@@ -3,7 +3,6 @@ import chalk from 'chalk';
|
||||
import { remove } from 'fs-extra';
|
||||
import { NowContext, ProjectLinkResult, ProjectSettings } from '../../types';
|
||||
import { NowConfig } from '../dev/types';
|
||||
import { Output } from '../output';
|
||||
import {
|
||||
getLinkedProject,
|
||||
linkFolderToProject,
|
||||
@@ -30,7 +29,6 @@ import Now from '../index';
|
||||
|
||||
export default async function setupAndLink(
|
||||
ctx: NowContext,
|
||||
output: Output,
|
||||
path: string,
|
||||
forceDelete: boolean,
|
||||
autoConfirm: boolean,
|
||||
@@ -39,15 +37,17 @@ export default async function setupAndLink(
|
||||
): Promise<ProjectLinkResult> {
|
||||
const {
|
||||
authConfig: { token },
|
||||
apiUrl,
|
||||
output,
|
||||
config,
|
||||
} = ctx;
|
||||
const { apiUrl } = ctx;
|
||||
const debug = output.isDebugEnabled();
|
||||
const client = new Client({
|
||||
apiUrl,
|
||||
token,
|
||||
currentTeam: config.currentTeam,
|
||||
debug,
|
||||
output,
|
||||
});
|
||||
|
||||
const isFile = !isDirectory(path);
|
||||
@@ -161,6 +161,7 @@ export default async function setupAndLink(
|
||||
apiUrl,
|
||||
token,
|
||||
debug,
|
||||
output,
|
||||
currentTeam: client.currentTeam,
|
||||
});
|
||||
const createArgs: any = {
|
||||
|
||||
@@ -3,16 +3,34 @@ import boxen from 'boxen';
|
||||
import { format } from 'util';
|
||||
import { Console } from 'console';
|
||||
import renderLink from './link';
|
||||
import wait from './wait';
|
||||
import wait, { StopSpinner } from './wait';
|
||||
|
||||
export type Output = ReturnType<typeof createOutput>;
|
||||
export type Output = ReturnType<typeof _createOutput>;
|
||||
|
||||
export interface OutputOptions {
|
||||
debug?: boolean;
|
||||
}
|
||||
|
||||
// Singleton
|
||||
let instance: Output | null = null;
|
||||
|
||||
export default function createOutput(opts?: OutputOptions) {
|
||||
if (!instance) {
|
||||
instance = _createOutput(opts);
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
function _createOutput({ debug: debugEnabled = false }: OutputOptions = {}) {
|
||||
let spinnerMessage = '';
|
||||
let spinner: StopSpinner | null = null;
|
||||
|
||||
export default function createOutput({ debug: debugEnabled = false } = {}) {
|
||||
function isDebugEnabled() {
|
||||
return debugEnabled;
|
||||
}
|
||||
|
||||
function print(str: string) {
|
||||
stopSpinner();
|
||||
process.stderr.write(str);
|
||||
}
|
||||
|
||||
@@ -94,18 +112,30 @@ export default function createOutput({ debug: debugEnabled = false } = {}) {
|
||||
}
|
||||
}
|
||||
|
||||
function spinner(message: string, delay: number = 300) {
|
||||
function setSpinner(message: string, delay: number = 300): void {
|
||||
spinnerMessage = message;
|
||||
if (debugEnabled) {
|
||||
debug(`Spinner invoked (${message}) with a ${delay}ms delay`);
|
||||
let isEnded = false;
|
||||
return () => {
|
||||
if (isEnded) return;
|
||||
isEnded = true;
|
||||
debug(`Spinner ended (${message})`);
|
||||
};
|
||||
return;
|
||||
}
|
||||
if (spinner) {
|
||||
spinner.text = message;
|
||||
} else {
|
||||
spinner = wait(message, delay);
|
||||
}
|
||||
}
|
||||
|
||||
return wait(message, delay);
|
||||
function stopSpinner() {
|
||||
if (debugEnabled && spinnerMessage) {
|
||||
const msg = `Spinner stopped (${spinnerMessage})`;
|
||||
spinnerMessage = '';
|
||||
debug(msg);
|
||||
}
|
||||
if (spinner) {
|
||||
spinner();
|
||||
spinner = null;
|
||||
spinnerMessage = '';
|
||||
}
|
||||
}
|
||||
|
||||
const c = {
|
||||
@@ -141,6 +171,7 @@ export default function createOutput({ debug: debugEnabled = false } = {}) {
|
||||
dim,
|
||||
time,
|
||||
note,
|
||||
spinner,
|
||||
spinner: setSpinner,
|
||||
stopSpinner,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
export { default, Output } from './create-output';
|
||||
export { StopSpinner } from './wait';
|
||||
|
||||
@@ -2,28 +2,50 @@ import ora from 'ora';
|
||||
import chalk from 'chalk';
|
||||
import eraseLines from './erase-lines';
|
||||
|
||||
export default function wait(msg: string, delay: number = 300, _ora = ora) {
|
||||
let spinner: ReturnType<typeof _ora>;
|
||||
let running = false;
|
||||
export interface StopSpinner {
|
||||
(): void;
|
||||
text: string;
|
||||
}
|
||||
|
||||
const planned = setTimeout(() => {
|
||||
export default function wait(
|
||||
msg: string,
|
||||
delay: number = 300,
|
||||
_ora = ora
|
||||
): StopSpinner {
|
||||
let spinner: ReturnType<typeof _ora> | null = null;
|
||||
|
||||
const timeout = setTimeout(() => {
|
||||
spinner = _ora(chalk.gray(msg));
|
||||
spinner.color = 'gray';
|
||||
spinner.start();
|
||||
running = true;
|
||||
}, delay);
|
||||
|
||||
const cancel = () => {
|
||||
clearTimeout(planned);
|
||||
if (running) {
|
||||
const stop = () => {
|
||||
clearTimeout(timeout);
|
||||
if (spinner) {
|
||||
spinner.stop();
|
||||
spinner = null;
|
||||
process.stderr.write(eraseLines(1));
|
||||
running = false;
|
||||
}
|
||||
process.removeListener('nowExit', cancel);
|
||||
};
|
||||
|
||||
stop.text = msg;
|
||||
|
||||
// Allow `text` property to update the text while the spinner is in action
|
||||
Object.defineProperty(stop, 'text', {
|
||||
get() {
|
||||
return msg;
|
||||
},
|
||||
|
||||
set(v: string) {
|
||||
msg = v;
|
||||
if (spinner) {
|
||||
spinner.text = chalk.gray(v);
|
||||
}
|
||||
},
|
||||
});
|
||||
|
||||
// @ts-ignore
|
||||
process.on('nowExit', cancel);
|
||||
return cancel;
|
||||
process.once('nowExit', stop);
|
||||
return stop;
|
||||
}
|
||||
|
||||
@@ -138,7 +138,7 @@ export async function getLinkedProject(
|
||||
return { status: 'not_linked', org: null, project: null };
|
||||
}
|
||||
|
||||
const spinner = output.spinner('Retrieving project…', 1000);
|
||||
output.spinner('Retrieving project…', 1000);
|
||||
let org: Org | null = null;
|
||||
let project: Project | ProjectNotFound | null = null;
|
||||
try {
|
||||
@@ -148,7 +148,7 @@ export async function getLinkedProject(
|
||||
]);
|
||||
} catch (err) {
|
||||
if (err?.status === 403) {
|
||||
spinner();
|
||||
output.stopSpinner();
|
||||
throw new NowBuildError({
|
||||
message: `Could not retrieve Project Settings. To link your Project, remove the ${outputCode(
|
||||
VERCEL_DIR
|
||||
@@ -161,7 +161,7 @@ export async function getLinkedProject(
|
||||
// Not a special case 403, we should still throw it
|
||||
throw err;
|
||||
} finally {
|
||||
spinner();
|
||||
output.stopSpinner();
|
||||
}
|
||||
|
||||
if (!org || !project || project instanceof ProjectNotFound) {
|
||||
@@ -176,7 +176,7 @@ export async function getLinkedProject(
|
||||
} else {
|
||||
output.print(
|
||||
prependEmoji(
|
||||
'Your project was either removed from Vercel or you’re not a member of it anymore.\n',
|
||||
'Your Project was either deleted, transferred to a new Team, or you don’t have access to it anymore.\n',
|
||||
emoji('warning')
|
||||
)
|
||||
);
|
||||
|
||||
2
packages/now-cli/test/dev/fixtures/test-clean-urls-with-output-directory/.gitignore
vendored
Normal file
2
packages/now-cli/test/dev/fixtures/test-clean-urls-with-output-directory/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
.vercel
|
||||
!public
|
||||
@@ -0,0 +1 @@
|
||||
About Page
|
||||
@@ -0,0 +1 @@
|
||||
Index Page
|
||||
@@ -0,0 +1 @@
|
||||
body { color: green }
|
||||
@@ -0,0 +1 @@
|
||||
Sub Another Page
|
||||
@@ -0,0 +1 @@
|
||||
Sub Index Page
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"version": 2,
|
||||
"cleanUrls": true,
|
||||
"trailingSlash": false
|
||||
}
|
||||
@@ -105,7 +105,8 @@ function validateResponseHeaders(t, res) {
|
||||
}
|
||||
|
||||
async function exec(directory, args = []) {
|
||||
return execa(binaryPath, ['dev', directory, ...args], {
|
||||
const token = await fetchCachedToken();
|
||||
return execa(binaryPath, ['dev', directory, '-t', token, ...args], {
|
||||
reject: false,
|
||||
shell: true,
|
||||
env: { __VERCEL_SKIP_DEV_CMD: 1 },
|
||||
@@ -166,9 +167,10 @@ async function testPath(
|
||||
async function testFixture(directory, opts = {}, args = []) {
|
||||
await runNpmInstall(directory);
|
||||
|
||||
const token = await fetchCachedToken();
|
||||
const dev = execa(
|
||||
binaryPath,
|
||||
['dev', directory, '-l', String(port), ...args],
|
||||
['dev', directory, '-t', token, '-l', String(port), ...args],
|
||||
{
|
||||
reject: false,
|
||||
detached: true,
|
||||
@@ -918,6 +920,32 @@ test(
|
||||
})
|
||||
);
|
||||
|
||||
test(
|
||||
'[vercel dev] test cleanUrls serve correct content when using `outputDirectory`',
|
||||
testFixtureStdio('test-clean-urls-with-output-directory', async testPath => {
|
||||
await testPath(200, '/', 'Index Page');
|
||||
await testPath(200, '/about', 'About Page');
|
||||
await testPath(200, '/sub', 'Sub Index Page');
|
||||
await testPath(200, '/sub/another', 'Sub Another Page');
|
||||
await testPath(200, '/style.css', 'body { color: green }');
|
||||
await testPath(308, '/index.html', 'Redirecting to / (308)', {
|
||||
Location: '/',
|
||||
});
|
||||
await testPath(308, '/about.html', 'Redirecting to /about (308)', {
|
||||
Location: '/about',
|
||||
});
|
||||
await testPath(308, '/sub/index.html', 'Redirecting to /sub (308)', {
|
||||
Location: '/sub',
|
||||
});
|
||||
await testPath(
|
||||
308,
|
||||
'/sub/another.html',
|
||||
'Redirecting to /sub/another (308)',
|
||||
{ Location: '/sub/another' }
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
test(
|
||||
'[vercel dev] should serve custom 404 when `cleanUrls: true`',
|
||||
testFixtureStdio('test-clean-urls-custom-404', async testPath => {
|
||||
|
||||
27
packages/now-cli/test/integration.js
vendored
27
packages/now-cli/test/integration.js
vendored
@@ -3,6 +3,7 @@ import path from 'path';
|
||||
import { URL, parse as parseUrl } from 'url';
|
||||
import test from 'ava';
|
||||
import semVer from 'semver';
|
||||
import { Readable } from 'stream';
|
||||
import { homedir } from 'os';
|
||||
import _execa from 'execa';
|
||||
import XDGAppPaths from 'xdg-app-paths';
|
||||
@@ -1171,11 +1172,11 @@ test('login with unregistered user', async t => {
|
||||
console.log(exitCode);
|
||||
|
||||
const goal = `Error! Please sign up: https://vercel.com/signup`;
|
||||
const lines = stdout.trim().split('\n');
|
||||
const lines = stderr.trim().split('\n');
|
||||
const last = lines[lines.length - 1];
|
||||
|
||||
t.is(exitCode, 1);
|
||||
t.is(last, goal);
|
||||
t.true(last.includes(goal));
|
||||
});
|
||||
|
||||
test('ignore files specified in .nowignore', async t => {
|
||||
@@ -1249,10 +1250,10 @@ test('list the scopes', async t => {
|
||||
|
||||
t.is(exitCode, 0);
|
||||
|
||||
const include = `✔ ${contextName} ${email}`;
|
||||
const include = new RegExp(`✔ ${contextName}\\s+${email}`);
|
||||
|
||||
t.true(
|
||||
stdout.includes(include),
|
||||
include.test(stdout),
|
||||
`Expected: ${include}\n\nReceived instead:\n${stdout}\n${stderr}`
|
||||
);
|
||||
});
|
||||
@@ -1335,12 +1336,23 @@ test('try to purchase a domain', async t => {
|
||||
return;
|
||||
}
|
||||
|
||||
const stream = new Readable();
|
||||
stream._read = () => {};
|
||||
|
||||
setTimeout(async () => {
|
||||
await sleep(ms('1s'));
|
||||
stream.push('y');
|
||||
await sleep(ms('1s'));
|
||||
stream.push('y');
|
||||
stream.push(null);
|
||||
}, ms('1s'));
|
||||
|
||||
const { stderr, stdout, exitCode } = await execa(
|
||||
binaryPath,
|
||||
['domains', 'buy', `${session}-test.org`, ...defaultArgs],
|
||||
{
|
||||
reject: false,
|
||||
input: 'y',
|
||||
input: stream,
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1588,7 +1600,8 @@ test('output logs with "short" output', async t => {
|
||||
t.truthy(
|
||||
stdout.match(
|
||||
/\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d\.\d+([+-][0-2]\d:[0-5]\d|Z)/
|
||||
)
|
||||
),
|
||||
formatOutput({ stderr, stdout })
|
||||
);
|
||||
|
||||
t.is(exitCode, 0);
|
||||
@@ -3120,7 +3133,7 @@ test('deploy shows notice when project in `.vercel` does not exists', async t =>
|
||||
detectedNotice =
|
||||
detectedNotice ||
|
||||
chunk.includes(
|
||||
'Your project was either removed from Vercel or you’re not a member of it anymore'
|
||||
'Your Project was either deleted, transferred to a new Team, or you don’t have access to it anymore'
|
||||
);
|
||||
|
||||
return /Set up and deploy [^?]+\?/.test(chunk);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/client",
|
||||
"version": "9.0.5",
|
||||
"version": "9.0.6",
|
||||
"main": "dist/index.js",
|
||||
"typings": "dist/index.d.ts",
|
||||
"homepage": "https://vercel.com",
|
||||
@@ -37,7 +37,7 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/build-utils": "2.7.0",
|
||||
"@vercel/build-utils": "2.9.0",
|
||||
"@zeit/fetch": "5.2.0",
|
||||
"async-retry": "1.2.3",
|
||||
"async-sema": "3.0.0",
|
||||
|
||||
1
packages/now-go/.gitignore
vendored
1
packages/now-go/.gitignore
vendored
@@ -3,4 +3,3 @@ dist
|
||||
*.log
|
||||
/go
|
||||
/analyze
|
||||
*.js
|
||||
|
||||
58
packages/now-go/build.js
Normal file
58
packages/now-go/build.js
Normal file
@@ -0,0 +1,58 @@
|
||||
#!/usr/bin/env node
|
||||
const fs = require('fs-extra');
|
||||
const execa = require('execa');
|
||||
const { join } = require('path');
|
||||
|
||||
async function main() {
|
||||
const outDir = join(__dirname, 'dist');
|
||||
|
||||
// Start fresh
|
||||
await fs.remove(outDir);
|
||||
|
||||
// Build with `ncc`
|
||||
await execa(
|
||||
'ncc',
|
||||
[
|
||||
'build',
|
||||
'index.ts',
|
||||
'-e',
|
||||
'@vercel/build-utils',
|
||||
'-e',
|
||||
'@now/build-utils',
|
||||
'-o',
|
||||
outDir,
|
||||
],
|
||||
{
|
||||
stdio: 'inherit',
|
||||
}
|
||||
);
|
||||
|
||||
const installDir = join(outDir, 'install');
|
||||
await execa(
|
||||
'ncc',
|
||||
[
|
||||
'build',
|
||||
'install.ts',
|
||||
'-e',
|
||||
'@vercel/build-utils',
|
||||
'-e',
|
||||
'@now/build-utils',
|
||||
'-o',
|
||||
installDir,
|
||||
],
|
||||
{
|
||||
stdio: 'inherit',
|
||||
}
|
||||
);
|
||||
|
||||
// Move compiled ncc file to out dir
|
||||
await fs.rename(join(installDir, 'index.js'), join(outDir, 'install.js'));
|
||||
|
||||
// Delete leftover "install" dir
|
||||
await fs.remove(installDir);
|
||||
}
|
||||
|
||||
main().catch(err => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
@@ -1,13 +0,0 @@
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
|
||||
# Start fresh
|
||||
rm -rf dist
|
||||
|
||||
# Build with `ncc`
|
||||
ncc build index.ts -e @vercel/build-utils -e @now/build-utils -o dist
|
||||
ncc build install.ts -e @vercel/build-utils -e @now/build-utils -o dist/install
|
||||
|
||||
# Move `install.js` to dist
|
||||
mv dist/install/index.js dist/install.js
|
||||
rm -rf dist/install
|
||||
@@ -125,7 +125,7 @@ Learn more: https://github.com/golang/go/wiki/Modules
|
||||
|
||||
const forceMove = Boolean(meta.isDev);
|
||||
const srcPath = join(goPath, 'src', 'lambda');
|
||||
let downloadPath = meta.isDev ? workPath : srcPath;
|
||||
let downloadPath = (meta.isDev || meta.skipDownload) ? workPath : srcPath;
|
||||
let downloadedFiles = await download(files, downloadPath, meta);
|
||||
|
||||
debug(`Parsing AST for "${entrypoint}"`);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/go",
|
||||
"version": "1.1.7",
|
||||
"version": "1.1.8",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/go",
|
||||
@@ -10,9 +10,9 @@
|
||||
"directory": "packages/now-go"
|
||||
},
|
||||
"scripts": {
|
||||
"build": "./build.sh",
|
||||
"build": "node build",
|
||||
"test-integration-once": "jest --env node --verbose --runInBand --bail",
|
||||
"prepublish": "./build.sh",
|
||||
"prepublish": "node build",
|
||||
"now-postinstall": "node dist/install.js"
|
||||
},
|
||||
"files": [
|
||||
|
||||
113
packages/now-node/build.js
Normal file
113
packages/now-node/build.js
Normal file
@@ -0,0 +1,113 @@
|
||||
#!/usr/bin/env node
|
||||
const fs = require('fs-extra');
|
||||
const execa = require('execa');
|
||||
const { join } = require('path');
|
||||
|
||||
async function main() {
|
||||
const srcDir = join(__dirname, 'src');
|
||||
const outDir = join(__dirname, 'dist');
|
||||
const bridgeDir = join(__dirname, '../now-node-bridge');
|
||||
|
||||
// Copy shared dependencies
|
||||
await Promise.all([
|
||||
fs.copyFile(join(bridgeDir, 'src/bridge.ts'), join(srcDir, 'bridge.ts')),
|
||||
fs.copyFile(
|
||||
join(bridgeDir, 'src/launcher.ts'),
|
||||
join(srcDir, 'launcher.ts')
|
||||
),
|
||||
]);
|
||||
|
||||
// Start fresh
|
||||
await fs.remove(outDir);
|
||||
|
||||
// Build TypeScript files
|
||||
await execa('tsc', [], {
|
||||
stdio: 'inherit',
|
||||
});
|
||||
|
||||
// Copy type file for ts test
|
||||
await fs.copyFile(
|
||||
join(outDir, 'types.d.ts'),
|
||||
join(__dirname, 'test/fixtures/15-helpers/ts/types.d.ts')
|
||||
);
|
||||
|
||||
// Setup symlink for symlink test
|
||||
const symlinkTarget = join(__dirname, 'test/fixtures/11-symlinks/symlink');
|
||||
await fs.remove(symlinkTarget);
|
||||
await fs.symlink('symlinked-asset', symlinkTarget);
|
||||
|
||||
// Use types.d.ts as the main types export
|
||||
await Promise.all(
|
||||
(await fs.readdir(outDir))
|
||||
.filter(p => p.endsWith('.d.ts') && p !== 'types.d.ts')
|
||||
.map(p => fs.remove(join(outDir, p)))
|
||||
);
|
||||
await fs.rename(join(outDir, 'types.d.ts'), join(outDir, 'index.d.ts'));
|
||||
|
||||
// Bundle helpers.ts with ncc
|
||||
await fs.remove(join(outDir, 'helpers.js'));
|
||||
const helpersDir = join(outDir, 'helpers');
|
||||
await execa(
|
||||
'ncc',
|
||||
[
|
||||
'build',
|
||||
join(srcDir, 'helpers.ts'),
|
||||
'-e',
|
||||
'@vercel/build-utils',
|
||||
'-e',
|
||||
'@now/build-utils',
|
||||
'-o',
|
||||
helpersDir,
|
||||
],
|
||||
{ stdio: 'inherit' }
|
||||
);
|
||||
await fs.rename(join(helpersDir, 'index.js'), join(outDir, 'helpers.js'));
|
||||
await fs.remove(helpersDir);
|
||||
|
||||
// Build source-map-support/register for source maps
|
||||
const sourceMapSupportDir = join(outDir, 'source-map-support');
|
||||
await execa(
|
||||
'ncc',
|
||||
[
|
||||
'build',
|
||||
join(__dirname, '../../node_modules/source-map-support/register'),
|
||||
'-e',
|
||||
'@vercel/build-utils',
|
||||
'-e',
|
||||
'@now/build-utils',
|
||||
'-o',
|
||||
sourceMapSupportDir,
|
||||
],
|
||||
{ stdio: 'inherit' }
|
||||
);
|
||||
await fs.rename(
|
||||
join(sourceMapSupportDir, 'index.js'),
|
||||
join(outDir, 'source-map-support.js')
|
||||
);
|
||||
await fs.remove(sourceMapSupportDir);
|
||||
|
||||
const mainDir = join(outDir, 'main');
|
||||
await execa(
|
||||
'ncc',
|
||||
[
|
||||
'build',
|
||||
join(srcDir, 'index.ts'),
|
||||
'-e',
|
||||
'@vercel/build-utils',
|
||||
'-e',
|
||||
'@now/build-utils',
|
||||
'-e',
|
||||
'typescript',
|
||||
'-o',
|
||||
mainDir,
|
||||
],
|
||||
{ stdio: 'inherit' }
|
||||
);
|
||||
await fs.rename(join(mainDir, 'index.js'), join(outDir, 'index.js'));
|
||||
await fs.remove(mainDir);
|
||||
}
|
||||
|
||||
main().catch(err => {
|
||||
console.error(err);
|
||||
process.exit(1);
|
||||
});
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user