mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-24 19:00:03 +00:00
Compare commits
23 Commits
@vercel/ne
...
@vercel/fr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
63cc9009c8 | ||
|
|
ccf6e3c432 | ||
|
|
8d015e3138 | ||
|
|
42f2fa1a20 | ||
|
|
8397aac0e3 | ||
|
|
7bcdc144eb | ||
|
|
624da9170d | ||
|
|
fb5b013a03 | ||
|
|
0a4bb53a58 | ||
|
|
2fbd9c78e3 | ||
|
|
1ed2b7a57d | ||
|
|
88cd9ca3c3 | ||
|
|
ecea2ca4a3 | ||
|
|
3f132bc15b | ||
|
|
61d95094c0 | ||
|
|
f7c47975e3 | ||
|
|
7c96f9f9a5 | ||
|
|
a5c805b6eb | ||
|
|
ff2a22023d | ||
|
|
c6efc028aa | ||
|
|
96565da1cf | ||
|
|
afb5e7fc85 | ||
|
|
34cc987be8 |
28
.github/CODEOWNERS
vendored
28
.github/CODEOWNERS
vendored
@@ -1,27 +1,27 @@
|
||||
# Documentation
|
||||
# https://help.github.com/en/articles/about-code-owners
|
||||
|
||||
* @tootallnate
|
||||
* @TooTallNate
|
||||
/.github/workflows @AndyBitz @styfle
|
||||
/packages/frameworks @AndyBitz
|
||||
/packages/now-cli/src/commands/dev/ @tootallnate @styfle @AndyBitz
|
||||
/packages/now-cli/src/util/dev/ @tootallnate @styfle @AndyBitz
|
||||
/packages/now-cli/src/commands/domains/ @javivelasco @mglagola @anatrajkovska
|
||||
/packages/now-cli/src/commands/certs/ @javivelasco @mglagola @anatrajkovska
|
||||
/packages/now-cli/src/commands/dev @TooTallNate @styfle @AndyBitz
|
||||
/packages/now-cli/src/util/dev @TooTallNate @styfle @AndyBitz
|
||||
/packages/now-cli/src/commands/domains @javivelasco @mglagola @anatrajkovska
|
||||
/packages/now-cli/src/commands/certs @javivelasco @mglagola @anatrajkovska
|
||||
/packages/now-cli/src/commands/env @styfle @lucleray
|
||||
/packages/now-client @rdev
|
||||
/packages/now-build-utils @styfle @AndyBitz
|
||||
/packages/now-node @styfle @tootallnate @lucleray
|
||||
/packages/now-node-bridge @styfle @tootallnate @lucleray
|
||||
/packages/now-client @rdev @styfle @TooTallNate
|
||||
/packages/now-build-utils @styfle @AndyBitz @TooTallNate
|
||||
/packages/now-node @styfle @TooTallNate @lucleray
|
||||
/packages/now-node-bridge @styfle @TooTallNate @lucleray
|
||||
/packages/now-next @Timer @ijjk
|
||||
/packages/now-go @styfle @sophearak
|
||||
/packages/now-python @styfle @sophearak
|
||||
/packages/now-ruby @styfle @coetry @nathancahill
|
||||
/packages/now-go @styfle @TooTallNate
|
||||
/packages/now-python @styfle @TooTallNate
|
||||
/packages/now-ruby @styfle @coetry @TooTallNate
|
||||
/packages/now-static-build @styfle @AndyBitz
|
||||
/packages/now-routing-utils @styfle @dav-is @ijjk
|
||||
/examples @mcsdevv @timothyis
|
||||
/examples/create-react-app @Timer
|
||||
/examples/nextjs @timneutkens
|
||||
/examples/nextjs @timneutkens @Timer
|
||||
/examples/hugo @mcsdevv @timothyis @styfle
|
||||
/examples/jekyll @mcsdevv @timothyis @sarupbanskota
|
||||
/examples/jekyll @mcsdevv @timothyis @styfle
|
||||
/examples/zola @mcsdevv @timothyis @styfle
|
||||
|
||||
14
errors/next-functions-config-optimized-lambdas.md
Normal file
14
errors/next-functions-config-optimized-lambdas.md
Normal file
@@ -0,0 +1,14 @@
|
||||
# `@vercel/next` Functions Config Optimized Lambdas Opt-out
|
||||
|
||||
#### Why This Warning Occurred
|
||||
|
||||
`@vercel/next` by default now bundles pages into optimized functions, minimizing bootup time and increasing overall application throughput.
|
||||
When the `functions` config is added in `now.json` or `vercel.json`, it causes conflicts with this optimization, so it is opted-out.
|
||||
|
||||
#### Possible Ways to Fix It
|
||||
|
||||
Remove the `functions` config from your `now.json` or `vercel.json` to take advantage of this optimization.
|
||||
|
||||
### Useful Links
|
||||
|
||||
- [Functions Config Documentation](https://vercel.com/docs/configuration?query=functions#project/functions)
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/frameworks",
|
||||
"version": "0.0.15-canary.4",
|
||||
"version": "0.0.15",
|
||||
"main": "frameworks.json",
|
||||
"license": "UNLICENSED",
|
||||
"scripts": {
|
||||
@@ -9,7 +9,7 @@
|
||||
"devDependencies": {
|
||||
"@types/jest": "24.0.22",
|
||||
"@types/node": "12.0.4",
|
||||
"ajv": "6.10.2",
|
||||
"ajv": "6.12.2",
|
||||
"jest": "24.9.0",
|
||||
"ts-jest": "24.1.0",
|
||||
"typescript": "3.9.3"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/build-utils",
|
||||
"version": "2.3.2-canary.4",
|
||||
"version": "2.4.0",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.js",
|
||||
|
||||
@@ -7,11 +7,13 @@ export class NowBuildError extends Error {
|
||||
public hideStackTrace = true;
|
||||
public code: string;
|
||||
public link?: string;
|
||||
public action?: string;
|
||||
|
||||
constructor({ message, code, link }: Props) {
|
||||
constructor({ message, code, link, action }: Props) {
|
||||
super(message);
|
||||
this.code = code;
|
||||
this.link = link;
|
||||
this.action = action;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,4 +33,8 @@ interface Props {
|
||||
* link to more information about this error.
|
||||
*/
|
||||
link?: string;
|
||||
/**
|
||||
* Optional "action" to display before the `link`, such as "More details".
|
||||
*/
|
||||
action?: string;
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import {
|
||||
getLatestNodeVersion,
|
||||
getDiscontinuedNodeVersions,
|
||||
} from './fs/node-version';
|
||||
import { NowBuildError } from './errors';
|
||||
import streamToBuffer from './fs/stream-to-buffer';
|
||||
import shouldServe from './should-serve';
|
||||
import debug from './debug';
|
||||
@@ -111,9 +112,11 @@ export const getPlatformEnv = (name: string): string | undefined => {
|
||||
const n = process.env[nName];
|
||||
if (typeof v === 'string') {
|
||||
if (typeof n === 'string') {
|
||||
throw new Error(
|
||||
`Both "${vName}" and "${nName}" env vars are defined. Please only define the "${vName}" env var`
|
||||
);
|
||||
throw new NowBuildError({
|
||||
code: 'CONFLICTING_ENV_VAR_NAMES',
|
||||
message: `Both "${vName}" and "${nName}" env vars are defined. Please only define the "${vName}" env var.`,
|
||||
link: 'https://vercel.link/combining-old-and-new-config',
|
||||
});
|
||||
}
|
||||
return v;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ describe('Test `getPlatformEnv()`', () => {
|
||||
assert(err);
|
||||
assert.equal(
|
||||
err!.message,
|
||||
'Both "VERCEL_FOO" and "NOW_FOO" env vars are defined. Please only define the "VERCEL_FOO" env var'
|
||||
'Both "VERCEL_FOO" and "NOW_FOO" env vars are defined. Please only define the "VERCEL_FOO" env var.'
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/cgi",
|
||||
"version": "1.0.6-canary.0",
|
||||
"version": "1.0.6",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vercel",
|
||||
"version": "19.0.2-canary.13",
|
||||
"version": "19.1.0",
|
||||
"preferGlobal": true,
|
||||
"license": "Apache-2.0",
|
||||
"description": "The command-line interface for Now",
|
||||
@@ -62,13 +62,13 @@
|
||||
"node": ">= 10"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/build-utils": "2.3.2-canary.4",
|
||||
"@vercel/go": "1.1.2-canary.2",
|
||||
"@vercel/next": "2.6.3-canary.6",
|
||||
"@vercel/node": "1.6.2-canary.5",
|
||||
"@vercel/python": "1.2.2-canary.2",
|
||||
"@vercel/ruby": "1.2.2-canary.1",
|
||||
"@vercel/static-build": "0.17.2-canary.1"
|
||||
"@vercel/build-utils": "2.4.0",
|
||||
"@vercel/go": "1.1.2",
|
||||
"@vercel/next": "2.6.6",
|
||||
"@vercel/node": "1.7.0",
|
||||
"@vercel/python": "1.2.2",
|
||||
"@vercel/ruby": "1.2.2",
|
||||
"@vercel/static-build": "0.17.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@sentry/node": "5.5.0",
|
||||
@@ -106,7 +106,7 @@
|
||||
"@zeit/fun": "0.11.2",
|
||||
"@zeit/ncc": "0.18.5",
|
||||
"@zeit/source-map-support": "0.6.2",
|
||||
"ajv": "6.10.2",
|
||||
"ajv": "6.12.2",
|
||||
"alpha-sort": "2.0.1",
|
||||
"ansi-escapes": "3.0.0",
|
||||
"ansi-regex": "3.0.0",
|
||||
@@ -136,6 +136,7 @@
|
||||
"escape-html": "1.0.3",
|
||||
"esm": "3.1.4",
|
||||
"execa": "3.2.0",
|
||||
"fast-deep-equal": "3.1.3",
|
||||
"fs-extra": "7.0.1",
|
||||
"get-port": "5.1.1",
|
||||
"glob": "7.1.2",
|
||||
|
||||
@@ -39,7 +39,6 @@ import {
|
||||
} from '../../util/errors-ts';
|
||||
import { SchemaValidationFailed } from '../../util/errors';
|
||||
import purchaseDomainIfAvailable from '../../util/domains/purchase-domain-if-available';
|
||||
import isWildcardAlias from '../../util/alias/is-wildcard-alias';
|
||||
import confirm from '../../util/input/confirm';
|
||||
import editProjectSettings from '../../util/input/edit-project-settings';
|
||||
import {
|
||||
@@ -56,6 +55,7 @@ import validatePaths, {
|
||||
} from '../../util/validate-paths';
|
||||
import { readLocalConfig } from '../../util/config/files';
|
||||
import { getCommandName } from '../../util/pkg-name.ts';
|
||||
import { getPreferredPreviewURL } from '../../util/deploy/get-preferred-preview-url.ts';
|
||||
|
||||
const addProcessEnv = async (log, env) => {
|
||||
let val;
|
||||
@@ -87,6 +87,7 @@ const addProcessEnv = async (log, env) => {
|
||||
|
||||
const printDeploymentStatus = async (
|
||||
output,
|
||||
client,
|
||||
{
|
||||
readyState,
|
||||
alias: aliasList,
|
||||
@@ -119,18 +120,14 @@ const printDeploymentStatus = async (
|
||||
let previewUrl;
|
||||
let isWildcard;
|
||||
if (!isFile && Array.isArray(aliasList) && aliasList.length > 0) {
|
||||
// search for a non now.sh/non wildcard domain
|
||||
// but fallback to the first alias in the list
|
||||
const mainAlias =
|
||||
aliasList.find(
|
||||
alias =>
|
||||
!alias.endsWith('.now.sh') &&
|
||||
!alias.endsWith('.vercel.app') &&
|
||||
!isWildcardAlias(alias)
|
||||
) || aliasList[0];
|
||||
|
||||
isWildcard = isWildcardAlias(mainAlias);
|
||||
previewUrl = isWildcard ? mainAlias : `https://${mainAlias}`;
|
||||
const previewUrlInfo = await getPreferredPreviewURL(client, aliasList);
|
||||
if (previewUrlInfo) {
|
||||
isWildcard = previewUrlInfo.isWildcard;
|
||||
previewUrl = previewUrlInfo.previewUrl;
|
||||
} else {
|
||||
isWildcard = false;
|
||||
previewUrl = `https://${deploymentUrl}`;
|
||||
}
|
||||
} else {
|
||||
// fallback to deployment url
|
||||
isWildcard = false;
|
||||
@@ -706,6 +703,12 @@ export default async function main(
|
||||
|
||||
return printDeploymentStatus(
|
||||
output,
|
||||
new Client({
|
||||
apiUrl: ctx.apiUrl,
|
||||
token: ctx.authConfig.token,
|
||||
currentTeam: org.type === 'team' ? org.id : null,
|
||||
debug: debugEnabled,
|
||||
}),
|
||||
deployment,
|
||||
deployStamp,
|
||||
!argv['--no-clipboard'],
|
||||
|
||||
@@ -119,7 +119,7 @@ export default async function main(ctx: NowContext) {
|
||||
try {
|
||||
return await dev(ctx, argv, args, output);
|
||||
} catch (err) {
|
||||
output.error(err.message);
|
||||
output.prettyError(err);
|
||||
output.debug(stringifyError(err));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
import chalk from 'chalk';
|
||||
import table from 'text-table';
|
||||
import mri from 'mri';
|
||||
import ms from 'ms';
|
||||
import strlen from '../util/strlen';
|
||||
import getArgs from '../util/get-args';
|
||||
import { handleError, error } from '../util/error';
|
||||
import exit from '../util/exit';
|
||||
import Client from '../util/client.ts';
|
||||
@@ -11,7 +11,6 @@ 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 getPrefixedFlags from '../util/get-prefixed-flags';
|
||||
import { getPkgName, getCommandName } from '../util/pkg-name.ts';
|
||||
|
||||
const e = encodeURIComponent;
|
||||
@@ -56,23 +55,25 @@ let apiUrl;
|
||||
let subcommand;
|
||||
|
||||
const main = async ctx => {
|
||||
argv = mri(ctx.argv.slice(2), {
|
||||
boolean: ['help'],
|
||||
alias: {
|
||||
help: 'h',
|
||||
next: 'N',
|
||||
},
|
||||
});
|
||||
try {
|
||||
argv = getArgs(ctx.argv.slice(2), {
|
||||
'--next': Number,
|
||||
'-N': '--next',
|
||||
});
|
||||
} catch (error) {
|
||||
handleError(error);
|
||||
return exit(1);
|
||||
}
|
||||
|
||||
argv._ = argv._.slice(1);
|
||||
|
||||
debug = argv.debug;
|
||||
debug = argv['--debug'];
|
||||
apiUrl = ctx.apiUrl;
|
||||
subcommand = argv._[0];
|
||||
subcommand = argv._[0] || 'list';
|
||||
|
||||
if (argv.help || !subcommand) {
|
||||
if (argv['--help']) {
|
||||
help();
|
||||
await exit(0);
|
||||
return exit(2);
|
||||
}
|
||||
|
||||
const output = createOutput({ debug });
|
||||
@@ -126,15 +127,16 @@ async function run({ client, contextName }) {
|
||||
)}`
|
||||
)
|
||||
);
|
||||
return exit(1);
|
||||
return exit(2);
|
||||
}
|
||||
|
||||
const stopSpinner = wait(`Fetching projects in ${chalk.bold(contextName)}`);
|
||||
|
||||
let projectsUrl = '/v4/projects/?limit=20';
|
||||
|
||||
if (argv.next) {
|
||||
projectsUrl += `&until=${argv.next}`;
|
||||
const next = argv['--next'];
|
||||
if (next) {
|
||||
projectsUrl += `&until=${next}`;
|
||||
}
|
||||
|
||||
const { projects: list, pagination } = await client.fetch(projectsUrl, {
|
||||
@@ -175,14 +177,7 @@ async function run({ client, contextName }) {
|
||||
}
|
||||
|
||||
if (pagination && pagination.count === 20) {
|
||||
const prefixedArgs = getPrefixedFlags(argv);
|
||||
const flags = getCommandFlags(prefixedArgs, [
|
||||
'_',
|
||||
'--next',
|
||||
'-N',
|
||||
'-d',
|
||||
'-y',
|
||||
]);
|
||||
const flags = getCommandFlags(argv, ['_', '--next', '-N', '-d', '-y']);
|
||||
const nextCmd = `projects ls${flags} --next ${pagination.next}`;
|
||||
console.log(`To display the next page run ${getCommandName(nextCmd)}`);
|
||||
}
|
||||
@@ -271,7 +266,7 @@ async function run({ client, contextName }) {
|
||||
|
||||
console.error(error('Please specify a valid subcommand: ls | add | rm'));
|
||||
help();
|
||||
exit(1);
|
||||
exit(2);
|
||||
}
|
||||
|
||||
process.on('uncaughtException', err => {
|
||||
|
||||
@@ -24,6 +24,7 @@ import checkForUpdate from 'update-check';
|
||||
import ms from 'ms';
|
||||
import { URL } from 'url';
|
||||
import * as Sentry from '@sentry/node';
|
||||
import { NowBuildError } from '@vercel/build-utils';
|
||||
import getGlobalPathConfig from './util/config/global-path';
|
||||
import {
|
||||
getDefaultConfig,
|
||||
@@ -114,10 +115,10 @@ const main = async argv_ => {
|
||||
}
|
||||
|
||||
if (
|
||||
localConfig instanceof NowError &&
|
||||
(localConfig instanceof NowError || localConfig instanceof NowBuildError) &&
|
||||
!(localConfig instanceof ERRORS.CantFindConfig)
|
||||
) {
|
||||
output.error(`Failed to load local config file: ${localConfig.message}`);
|
||||
output.prettyError(localConfig);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -644,27 +645,6 @@ const main = async argv_ => {
|
||||
)} could not be resolved. Please verify your internet connectivity and DNS configuration.`
|
||||
);
|
||||
output.debug(err.stack);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
await reportError(Sentry, err, apiUrl, configFiles);
|
||||
|
||||
// If there is a code we should not consider the error unexpected
|
||||
// but instead show the message. Any error that is handled by this should
|
||||
// actually be handled in the sub command instead. Please make sure
|
||||
// that happens for anything that lands here. It should NOT bubble up to here.
|
||||
if (err.code) {
|
||||
output.debug(err.stack);
|
||||
output.error(err.message);
|
||||
|
||||
if (shouldCollectMetrics) {
|
||||
metric
|
||||
.event(eventCategory, '1', pkg.version)
|
||||
.exception(err.message)
|
||||
.send();
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -675,9 +655,23 @@ const main = async argv_ => {
|
||||
.send();
|
||||
}
|
||||
|
||||
// Otherwise it is an unexpected error and we should show the trace
|
||||
// and an unexpected error message
|
||||
output.error(`An unexpected error occurred in ${subcommand}: ${err.stack}`);
|
||||
// If there is a code we should not consider the error unexpected
|
||||
// but instead show the message. Any error that is handled by this should
|
||||
// actually be handled in the sub command instead. Please make sure
|
||||
// that happens for anything that lands here. It should NOT bubble up to here.
|
||||
if (err.code) {
|
||||
output.debug(err.stack);
|
||||
output.prettyError(err);
|
||||
} else {
|
||||
await reportError(Sentry, err, apiUrl, configFiles);
|
||||
|
||||
// Otherwise it is an unexpected error and we should show the trace
|
||||
// and an unexpected error message
|
||||
output.error(
|
||||
`An unexpected error occurred in ${subcommand}: ${err.stack}`
|
||||
);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -688,8 +682,6 @@ const main = async argv_ => {
|
||||
return exitCode;
|
||||
};
|
||||
|
||||
debug('start');
|
||||
|
||||
const handleRejection = async err => {
|
||||
debug('handling rejection');
|
||||
|
||||
|
||||
17
packages/now-cli/src/util/certs/get-certs-for-cn.ts
Normal file
17
packages/now-cli/src/util/certs/get-certs-for-cn.ts
Normal file
@@ -0,0 +1,17 @@
|
||||
import { stringify } from 'querystring';
|
||||
import { Cert } from '../../types';
|
||||
import Client from '../client';
|
||||
|
||||
/**
|
||||
* Returns certs that contain @param cn.
|
||||
*/
|
||||
export async function getCertsForCn(
|
||||
client: Client,
|
||||
cn: string,
|
||||
{ limit }: { limit?: number } = {}
|
||||
) {
|
||||
const { certs } = await client.fetch<{
|
||||
certs: Cert[];
|
||||
}>(`/v4/now/certs?${stringify({ cn, ...(limit ? { limit } : {}) })}`);
|
||||
return certs;
|
||||
}
|
||||
@@ -24,7 +24,7 @@ export default class Client extends EventEmitter {
|
||||
_withCache: boolean;
|
||||
_output: Output;
|
||||
_token: string;
|
||||
currentTeam?: string;
|
||||
currentTeam?: string | null;
|
||||
|
||||
constructor({
|
||||
apiUrl,
|
||||
@@ -36,7 +36,7 @@ export default class Client extends EventEmitter {
|
||||
}: {
|
||||
apiUrl: string;
|
||||
token: string;
|
||||
currentTeam?: string;
|
||||
currentTeam?: string | null;
|
||||
forceNew?: boolean;
|
||||
withCache?: boolean;
|
||||
debug?: boolean;
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
import isWildcardAlias from '../alias/is-wildcard-alias';
|
||||
import { getCertsForCn } from '../certs/get-certs-for-cn';
|
||||
import Client from '../client';
|
||||
|
||||
/**
|
||||
* Tries to find the "best" alias url.
|
||||
* @param aliasList
|
||||
*/
|
||||
export async function getPreferredPreviewURL(
|
||||
client: Client,
|
||||
aliasList: string[]
|
||||
) {
|
||||
if (aliasList.length === 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* First checks for non public aliases and non wildcard domains.
|
||||
*/
|
||||
const preferredAliases = aliasList.filter(
|
||||
alias =>
|
||||
!alias.endsWith('.now.sh') &&
|
||||
!alias.endsWith('.vercel.app') &&
|
||||
!isWildcardAlias(alias)
|
||||
);
|
||||
for (const alias of preferredAliases) {
|
||||
const certs = await getCertsForCn(client, alias, { limit: 1 }).catch(() => {
|
||||
return null;
|
||||
});
|
||||
if (certs && certs.length > 0) {
|
||||
return { previewUrl: `https://${alias}`, isWildcard: false };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fallback to first alias
|
||||
*/
|
||||
const [firstAlias] = aliasList;
|
||||
if (isWildcardAlias(firstAlias)) {
|
||||
return { previewUrl: firstAlias, isWildcard: true };
|
||||
}
|
||||
|
||||
if (firstAlias.endsWith('.vercel.app') || firstAlias.endsWith('.now.sh')) {
|
||||
return { previewUrl: `https://${firstAlias}`, isWildcard: false };
|
||||
}
|
||||
|
||||
return { previewUrl: `http://${firstAlias}`, isWildcard: false };
|
||||
}
|
||||
@@ -3,9 +3,9 @@ import semver from 'semver';
|
||||
import npa from 'npm-package-arg';
|
||||
import pluralize from 'pluralize';
|
||||
import { basename, join } from 'path';
|
||||
import { PackageJson } from '@vercel/build-utils';
|
||||
import XDGAppPaths from 'xdg-app-paths';
|
||||
import { mkdirp, readJSON, writeJSON } from 'fs-extra';
|
||||
import { NowBuildError, PackageJson } from '@vercel/build-utils';
|
||||
import cliPkg from '../pkg';
|
||||
|
||||
import { NoBuilderCacheError } from '../errors-ts';
|
||||
@@ -232,21 +232,41 @@ async function npmInstall(
|
||||
output.debug(`Running npm install in ${cwd}`);
|
||||
|
||||
try {
|
||||
await execa(
|
||||
'npm',
|
||||
[
|
||||
'install',
|
||||
'--save-exact',
|
||||
'--no-package-lock',
|
||||
'--no-audit',
|
||||
'--no-progress',
|
||||
...sortedPackages,
|
||||
],
|
||||
{
|
||||
cwd,
|
||||
stdio: output.isDebugEnabled() ? 'inherit' : undefined,
|
||||
const args = [
|
||||
'install',
|
||||
'--save-exact',
|
||||
'--no-package-lock',
|
||||
'--no-audit',
|
||||
'--no-progress',
|
||||
];
|
||||
if (process.stderr.isTTY) {
|
||||
// Force colors in the npm child process
|
||||
// https://docs.npmjs.com/misc/config#color
|
||||
args.push('--color=always');
|
||||
}
|
||||
args.push(...sortedPackages);
|
||||
const result = await execa('npm', args, {
|
||||
cwd,
|
||||
reject: false,
|
||||
stdio: output.isDebugEnabled() ? 'inherit' : 'pipe',
|
||||
});
|
||||
if (result.failed) {
|
||||
stopSpinner();
|
||||
if (result.stdout) {
|
||||
console.log(result.stdout);
|
||||
}
|
||||
);
|
||||
if (result.stderr) {
|
||||
console.error(result.stderr);
|
||||
}
|
||||
throw new NowBuildError({
|
||||
message:
|
||||
(result as any).code === 'ENOENT'
|
||||
? '`npm` is not installed'
|
||||
: 'Failed to install `vercel dev` dependencies',
|
||||
code: 'NPM_INSTALL_ERROR',
|
||||
link: 'https://vercel.link/npm-install-failed-dev',
|
||||
});
|
||||
}
|
||||
} finally {
|
||||
stopSpinner();
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import directoryTemplate from 'serve-handler/src/directory';
|
||||
import getPort from 'get-port';
|
||||
import { ChildProcess } from 'child_process';
|
||||
import isPortReachable from 'is-port-reachable';
|
||||
import deepEqual from 'fast-deep-equal';
|
||||
import which from 'which';
|
||||
|
||||
import { getVercelIgnore, fileNameSymbol } from '@vercel/client';
|
||||
@@ -114,6 +115,7 @@ export default class DevServer {
|
||||
public cwd: string;
|
||||
public debug: boolean;
|
||||
public output: Output;
|
||||
public proxy: httpProxy;
|
||||
public envConfigs: EnvConfigs;
|
||||
public frameworkSlug: string | null;
|
||||
public files: BuilderInputs;
|
||||
@@ -124,7 +126,6 @@ export default class DevServer {
|
||||
private caseSensitive: boolean;
|
||||
private apiDir: string | null;
|
||||
private apiExtensions: Set<string>;
|
||||
private proxy: httpProxy;
|
||||
private server: http.Server;
|
||||
private stopping: boolean;
|
||||
private buildMatches: Map<string, BuildMatch>;
|
||||
@@ -234,8 +235,18 @@ export default class DevServer {
|
||||
}
|
||||
}
|
||||
|
||||
// Update the build matches in case an entrypoint was created or deleted
|
||||
const nowConfig = await this.getNowConfig(false);
|
||||
|
||||
// Update the env vars configuration
|
||||
const nowConfigBuild = nowConfig.build || {};
|
||||
const [runEnv, buildEnv] = await Promise.all([
|
||||
this.getLocalEnv('.env', nowConfig.env),
|
||||
this.getLocalEnv('.env.build', nowConfigBuild.env),
|
||||
]);
|
||||
const allEnv = { ...buildEnv, ...runEnv };
|
||||
this.envConfigs = { buildEnv, runEnv, allEnv };
|
||||
|
||||
// Update the build matches in case an entrypoint was created or deleted
|
||||
await this.updateBuildMatches(nowConfig);
|
||||
|
||||
const filesChangedArray = [...filesChanged];
|
||||
@@ -400,7 +411,7 @@ export default class DevServer {
|
||||
const blockingBuilds: Promise<void>[] = [];
|
||||
for (const match of matches) {
|
||||
const currentMatch = this.buildMatches.get(match.src);
|
||||
if (!currentMatch || currentMatch.use !== match.use) {
|
||||
if (!buildMatchEquals(currentMatch, match)) {
|
||||
this.output.debug(
|
||||
`Adding build match for "${match.src}" with "${match.use}"`
|
||||
);
|
||||
@@ -522,18 +533,11 @@ export default class DevServer {
|
||||
// The default empty `vercel.json` is used to serve all files as static
|
||||
// when no `vercel.json` is present
|
||||
let configPath = 'vercel.json';
|
||||
let config: NowConfig = this.cachedNowConfig || {
|
||||
let config: NowConfig = {
|
||||
version: 2,
|
||||
[fileNameSymbol]: configPath,
|
||||
};
|
||||
|
||||
// We need to delete these properties for zero config to work
|
||||
// with file changes
|
||||
if (this.cachedNowConfig) {
|
||||
delete this.cachedNowConfig.builds;
|
||||
delete this.cachedNowConfig.routes;
|
||||
}
|
||||
|
||||
try {
|
||||
configPath = getNowConfigPath(this.cwd);
|
||||
this.output.debug(`Reading ${configPath}`);
|
||||
@@ -564,7 +568,7 @@ export default class DevServer {
|
||||
nowConfig: config,
|
||||
});
|
||||
if (routeError) {
|
||||
this.output.error(routeError.message, null, routeError.link);
|
||||
this.output.prettyError(routeError);
|
||||
await this.exit();
|
||||
}
|
||||
config.routes = maybeRoutes || [];
|
||||
@@ -773,7 +777,6 @@ export default class DevServer {
|
||||
this.getLocalEnv('.env.build', nowConfigBuild.env),
|
||||
]);
|
||||
const allEnv = { ...buildEnv, ...runEnv };
|
||||
Object.assign(process.env, allEnv);
|
||||
this.envConfigs = { buildEnv, runEnv, allEnv };
|
||||
|
||||
const opts = { output: this.output, isBuilds: true };
|
||||
@@ -1367,7 +1370,7 @@ export default class DevServer {
|
||||
|
||||
debug(`ProxyPass: ${destUrl}`);
|
||||
this.setResponseHeaders(res, nowRequestId);
|
||||
return proxyPass(req, res, destUrl, this.proxy, this.output);
|
||||
return proxyPass(req, res, destUrl, this, nowRequestId);
|
||||
}
|
||||
|
||||
match = await findBuildMatch(
|
||||
@@ -1506,8 +1509,8 @@ export default class DevServer {
|
||||
req,
|
||||
res,
|
||||
`http://localhost:${this.devProcessPort}`,
|
||||
this.proxy,
|
||||
this.output,
|
||||
this,
|
||||
nowRequestId,
|
||||
false
|
||||
);
|
||||
}
|
||||
@@ -1626,8 +1629,8 @@ export default class DevServer {
|
||||
req,
|
||||
res,
|
||||
`http://localhost:${port}`,
|
||||
this.proxy,
|
||||
this.output,
|
||||
this,
|
||||
nowRequestId,
|
||||
false
|
||||
);
|
||||
} else {
|
||||
@@ -1656,8 +1659,8 @@ export default class DevServer {
|
||||
req,
|
||||
res,
|
||||
`http://localhost:${this.devProcessPort}`,
|
||||
this.proxy,
|
||||
this.output,
|
||||
this,
|
||||
nowRequestId,
|
||||
false
|
||||
);
|
||||
}
|
||||
@@ -1967,24 +1970,27 @@ function proxyPass(
|
||||
req: http.IncomingMessage,
|
||||
res: http.ServerResponse,
|
||||
dest: string,
|
||||
proxy: httpProxy,
|
||||
output: Output,
|
||||
devServer: DevServer,
|
||||
nowRequestId: string,
|
||||
ignorePath: boolean = true
|
||||
): void {
|
||||
return proxy.web(
|
||||
return devServer.proxy.web(
|
||||
req,
|
||||
res,
|
||||
{ target: dest, ignorePath },
|
||||
(error: NodeJS.ErrnoException) => {
|
||||
// If the client hangs up a socket, we do not
|
||||
// want to do anything, as the client just expects
|
||||
// the connection to be closed.
|
||||
if (error.code === 'ECONNRESET') {
|
||||
res.end();
|
||||
return;
|
||||
devServer.output.error(
|
||||
`Failed to complete request to ${req.url}: ${error}`
|
||||
);
|
||||
if (!res.headersSent) {
|
||||
devServer.sendError(
|
||||
req,
|
||||
res,
|
||||
nowRequestId,
|
||||
'NO_RESPONSE_FROM_FUNCTION',
|
||||
502
|
||||
);
|
||||
}
|
||||
|
||||
output.error(`Failed to complete request to ${req.url}: ${error}`);
|
||||
}
|
||||
);
|
||||
}
|
||||
@@ -2258,3 +2264,11 @@ function hasNewRoutingProperties(nowConfig: NowConfig) {
|
||||
typeof nowConfig.trailingSlash !== undefined
|
||||
);
|
||||
}
|
||||
|
||||
function buildMatchEquals(a?: BuildMatch, b?: BuildMatch): boolean {
|
||||
if (!a || !b) return false;
|
||||
if (a.src !== b.src) return false;
|
||||
if (a.use !== b.use) return false;
|
||||
if (!deepEqual(a.config || {}, b.config || {})) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import bytes from 'bytes';
|
||||
import { Response } from 'node-fetch';
|
||||
import { NowBuildError } from '@vercel/build-utils';
|
||||
import { NowError } from './now-error';
|
||||
import code from './output/code';
|
||||
import { getCommandName } from './pkg-name';
|
||||
@@ -771,17 +772,17 @@ export class CantParseJSONFile extends NowError<
|
||||
}
|
||||
}
|
||||
|
||||
export class ConflictingConfigFiles extends NowError<
|
||||
'CONFLICTING_CONFIG_FILES',
|
||||
{ files: string[] }
|
||||
> {
|
||||
export class ConflictingConfigFiles extends NowBuildError {
|
||||
files: string[];
|
||||
|
||||
constructor(files: string[]) {
|
||||
super({
|
||||
code: 'CONFLICTING_CONFIG_FILES',
|
||||
meta: { files },
|
||||
message:
|
||||
'Cannot use both a `vercel.json` and `now.json` file. Please delete the `now.json` file.',
|
||||
link: 'https://vercel.link/combining-old-and-new-config',
|
||||
});
|
||||
this.files = files;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ import chalk from 'chalk';
|
||||
import boxen from 'boxen';
|
||||
import { format } from 'util';
|
||||
import { Console } from 'console';
|
||||
import renderLink from './link';
|
||||
import wait from './wait';
|
||||
|
||||
export type Output = ReturnType<typeof createOutput>;
|
||||
@@ -41,7 +42,7 @@ export default function createOutput({ debug: debugEnabled = false } = {}) {
|
||||
boxen(
|
||||
chalk.bold.yellow('WARN! ') +
|
||||
str +
|
||||
(details ? `\nMore details: ${details}` : ''),
|
||||
(details ? `\nMore details: ${renderLink(details)}` : ''),
|
||||
{
|
||||
padding: {
|
||||
top: 0,
|
||||
@@ -64,17 +65,21 @@ export default function createOutput({ debug: debugEnabled = false } = {}) {
|
||||
|
||||
function error(
|
||||
str: string,
|
||||
slug: string | null = null,
|
||||
link: string | null = null,
|
||||
slug?: string,
|
||||
link?: string,
|
||||
action = 'More details'
|
||||
) {
|
||||
print(`${chalk.red(`Error!`)} ${str}\n`);
|
||||
const details = slug ? `https://err.sh/now/${slug}` : link;
|
||||
if (details) {
|
||||
print(`${action}: ${details}\n`);
|
||||
print(`${chalk.bold(action)}: ${renderLink(details)}\n`);
|
||||
}
|
||||
}
|
||||
|
||||
function prettyError(err: Error & { link?: string; action?: string }) {
|
||||
return error(err.message, undefined, err.link, err.action);
|
||||
}
|
||||
|
||||
function ready(str: string) {
|
||||
print(`${chalk.cyan('> Ready!')} ${str}\n`);
|
||||
}
|
||||
@@ -107,8 +112,6 @@ export default function createOutput({ debug: debugEnabled = false } = {}) {
|
||||
return wait(message, delay);
|
||||
}
|
||||
|
||||
// This is pretty hacky, but since we control the version of Node.js
|
||||
// being used because of `pkg` it's safe to do in this case.
|
||||
const c = {
|
||||
_times: new Map(),
|
||||
log(a: string, ...args: string[]) {
|
||||
@@ -135,6 +138,7 @@ export default function createOutput({ debug: debugEnabled = false } = {}) {
|
||||
log,
|
||||
warn,
|
||||
error,
|
||||
prettyError,
|
||||
ready,
|
||||
success,
|
||||
debug,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import chalk from 'chalk';
|
||||
import { metrics, shouldCollectMetrics } from '../metrics';
|
||||
import { APIError } from '../errors-ts';
|
||||
import renderLink from './link';
|
||||
|
||||
const metric = metrics();
|
||||
|
||||
@@ -9,10 +10,9 @@ export default function error(...input: string[] | [APIError]) {
|
||||
if (typeof input[0] === 'object') {
|
||||
const { slug, message, link } = input[0];
|
||||
messages = [message];
|
||||
if (slug) {
|
||||
messages.push(`> More details: https://err.sh/now/${slug}`);
|
||||
} else if (link) {
|
||||
messages.push(`> More details: ${link}`);
|
||||
const details = slug ? `https://err.sh/now/${slug}` : link;
|
||||
if (details) {
|
||||
messages.push(`${chalk.bold('More details')}: ${renderLink(details)}`);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import chalk from 'chalk';
|
||||
import { prependEmoji, emoji } from '../emoji';
|
||||
import AJV from 'ajv';
|
||||
import { isDirectory } from '../config/global-path';
|
||||
import { getPlatformEnv } from '@vercel/build-utils';
|
||||
import { NowBuildError, getPlatformEnv } from '@vercel/build-utils';
|
||||
|
||||
const readFile = promisify(fs.readFile);
|
||||
const writeFile = promisify(fs.writeFile);
|
||||
@@ -49,9 +49,12 @@ export function getVercelDirectory(cwd: string = process.cwd()): string {
|
||||
const possibleDirs = [join(cwd, VERCEL_DIR), join(cwd, VERCEL_DIR_FALLBACK)];
|
||||
const existingDirs = possibleDirs.filter(d => isDirectory(d));
|
||||
if (existingDirs.length > 1) {
|
||||
throw new Error(
|
||||
'Both `.vercel` and `.now` directories exist. Please remove the `.now` directory.'
|
||||
);
|
||||
throw new NowBuildError({
|
||||
code: 'CONFLICTING_CONFIG_DIRECTORIES',
|
||||
message:
|
||||
'Both `.vercel` and `.now` directories exist. Please remove the `.now` directory.',
|
||||
link: 'https://vercel.link/combining-old-and-new-config',
|
||||
});
|
||||
}
|
||||
return existingDirs[0] || possibleDirs[0];
|
||||
}
|
||||
|
||||
1
packages/now-cli/test/dev/fixtures/force-module-commonjs/.gitignore
vendored
Normal file
1
packages/now-cli/test/dev/fixtures/force-module-commonjs/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
.vercel
|
||||
@@ -0,0 +1,3 @@
|
||||
export default function(req, res) {
|
||||
res.end('Force "module: commonjs" JavaScript with ES Modules API endpoint');
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import { IncomingMessage, ServerResponse } from 'http';
|
||||
|
||||
export default function(req: IncomingMessage, res: ServerResponse) {
|
||||
res.end('Force "module: commonjs" TypeScript API endpoint');
|
||||
}
|
||||
2
packages/now-cli/test/dev/fixtures/force-module-commonjs/next-env.d.ts
vendored
Normal file
2
packages/now-cli/test/dev/fixtures/force-module-commonjs/next-env.d.ts
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/// <reference types="next" />
|
||||
/// <reference types="next/types/global" />
|
||||
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "force-module-commonjs",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "next",
|
||||
"build": "next build",
|
||||
"start": "next start"
|
||||
},
|
||||
"dependencies": {
|
||||
"next": "^9.3.4",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "14.0.9",
|
||||
"@types/react": "^16.9.32",
|
||||
"typescript": "^3.8.3"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export default function () {
|
||||
return <div>Force "module: commonjs" test page</div>;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"target": "esnext",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": true,
|
||||
"allowSyntheticDefaultImports": true,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noEmit": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve",
|
||||
"paths": {
|
||||
"@components/*": ["components/*"],
|
||||
"@lib/*": ["lib/*"]
|
||||
}
|
||||
},
|
||||
"exclude": ["node_modules", "api"],
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"]
|
||||
}
|
||||
5633
packages/now-cli/test/dev/fixtures/force-module-commonjs/yarn.lock
Normal file
5633
packages/now-cli/test/dev/fixtures/force-module-commonjs/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,3 @@
|
||||
export default (req, res) => {
|
||||
res.send(process.env);
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
{ "env": { "FOO": "bar" } }
|
||||
10
packages/now-cli/test/dev/fixtures/node-helpers/index.js
Normal file
10
packages/now-cli/test/dev/fixtures/node-helpers/index.js
Normal file
@@ -0,0 +1,10 @@
|
||||
export default (req, res) => {
|
||||
const hasHelpers = typeof req.query !== 'undefined';
|
||||
res.setHeader('Content-Type', 'application/json');
|
||||
res.end(
|
||||
JSON.stringify({
|
||||
hasHelpers,
|
||||
query: req.query,
|
||||
})
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1 @@
|
||||
{ "builds": [{ "src": "index.js", "use": "@vercel/node@canary" }] }
|
||||
@@ -0,0 +1,3 @@
|
||||
{
|
||||
"builds": [{ "src": "*.js", "use": "@vercel/does-not-exist" }]
|
||||
}
|
||||
@@ -161,7 +161,7 @@ async function testPath(
|
||||
Object.entries(headers).forEach(([key, expectedValue]) => {
|
||||
let actualValue = res.headers.get(key);
|
||||
if (key.toLowerCase() === 'location' && actualValue === '//') {
|
||||
// HACK: `node-fetch` has strang behavior for location header so fix it
|
||||
// HACK: `node-fetch` has strange behavior for location header so fix it
|
||||
// with `manual-dont-change` opt and convert double slash to single.
|
||||
// See https://github.com/node-fetch/node-fetch/issues/417#issuecomment-587233352
|
||||
actualValue = '/';
|
||||
@@ -187,20 +187,29 @@ async function testFixture(directory, opts = {}, args = []) {
|
||||
}
|
||||
);
|
||||
|
||||
const stdoutList = [];
|
||||
const stderrList = [];
|
||||
|
||||
let stdout = '';
|
||||
let stderr = '';
|
||||
const readyResolver = createResolver();
|
||||
const exitResolver = createResolver();
|
||||
|
||||
dev.stderr.on('data', data => stderrList.push(Buffer.from(data)));
|
||||
dev.stdout.on('data', data => stdoutList.push(Buffer.from(data)));
|
||||
dev.stdout.setEncoding('utf8');
|
||||
dev.stderr.setEncoding('utf8');
|
||||
|
||||
dev.stdout.on('data', data => {
|
||||
stdout += data;
|
||||
});
|
||||
dev.stderr.on('data', data => {
|
||||
stderr += data;
|
||||
|
||||
if (stderr.includes('Ready! Available at')) {
|
||||
readyResolver.resolve();
|
||||
}
|
||||
});
|
||||
|
||||
let printedOutput = false;
|
||||
|
||||
dev.on('exit', () => {
|
||||
if (!printedOutput) {
|
||||
const stdout = Buffer.concat(stdoutList).toString();
|
||||
const stderr = Buffer.concat(stderrList).toString();
|
||||
printOutput(directory, stdout, stderr);
|
||||
printedOutput = true;
|
||||
}
|
||||
@@ -209,8 +218,6 @@ async function testFixture(directory, opts = {}, args = []) {
|
||||
|
||||
dev.on('error', () => {
|
||||
if (!printedOutput) {
|
||||
const stdout = Buffer.concat(stdoutList).toString();
|
||||
const stderr = Buffer.concat(stderrList).toString();
|
||||
printOutput(directory, stdout, stderr);
|
||||
printedOutput = true;
|
||||
}
|
||||
@@ -226,6 +233,7 @@ async function testFixture(directory, opts = {}, args = []) {
|
||||
return {
|
||||
dev,
|
||||
port,
|
||||
readyResolver,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -267,14 +275,12 @@ function testFixtureStdio(
|
||||
|
||||
await runNpmInstall(cwd);
|
||||
|
||||
const stdoutList = [];
|
||||
const stderrList = [];
|
||||
|
||||
let stdout = '';
|
||||
let stderr = '';
|
||||
const readyResolver = createResolver();
|
||||
const exitResolver = createResolver();
|
||||
|
||||
try {
|
||||
let stderr = '';
|
||||
let printedOutput = false;
|
||||
|
||||
const env = skipDeploy
|
||||
@@ -285,17 +291,19 @@ function testFixtureStdio(
|
||||
env,
|
||||
});
|
||||
|
||||
dev.stdout.setEncoding('utf8');
|
||||
dev.stderr.setEncoding('utf8');
|
||||
|
||||
dev.stdout.pipe(process.stdout);
|
||||
dev.stderr.pipe(process.stderr);
|
||||
|
||||
dev.stdout.on('data', data => {
|
||||
stdoutList.push(data);
|
||||
stdout += data;
|
||||
});
|
||||
|
||||
dev.stderr.on('data', data => {
|
||||
stderrList.push(data);
|
||||
stderr += data;
|
||||
|
||||
stderr += data.toString();
|
||||
if (stderr.includes('Ready! Available at')) {
|
||||
readyResolver.resolve();
|
||||
}
|
||||
@@ -315,8 +323,6 @@ function testFixtureStdio(
|
||||
|
||||
dev.on('exit', () => {
|
||||
if (!printedOutput) {
|
||||
const stdout = Buffer.concat(stdoutList).toString();
|
||||
const stderr = Buffer.concat(stderrList).toString();
|
||||
printOutput(directory, stdout, stderr);
|
||||
printedOutput = true;
|
||||
}
|
||||
@@ -325,8 +331,6 @@ function testFixtureStdio(
|
||||
|
||||
dev.on('error', () => {
|
||||
if (!printedOutput) {
|
||||
const stdout = Buffer.concat(stdoutList).toString();
|
||||
const stderr = Buffer.concat(stderrList).toString();
|
||||
printOutput(directory, stdout, stderr);
|
||||
printedOutput = true;
|
||||
}
|
||||
@@ -375,6 +379,153 @@ test.afterEach(async () => {
|
||||
);
|
||||
});
|
||||
|
||||
test('[vercel dev] prints `npm install` errors', async t => {
|
||||
const dir = fixture('runtime-not-installed');
|
||||
const result = await exec(dir);
|
||||
t.truthy(result.stderr.includes('npm ERR! 404'));
|
||||
t.truthy(
|
||||
result.stderr.includes('Failed to install `vercel dev` dependencies')
|
||||
);
|
||||
t.truthy(
|
||||
result.stderr.includes('https://vercel.link/npm-install-failed-dev')
|
||||
);
|
||||
});
|
||||
|
||||
test('[vercel dev] `vercel.json` should be invalidated if deleted', async t => {
|
||||
const dir = fixture('invalidate-vercel-config');
|
||||
const configPath = join(dir, 'vercel.json');
|
||||
const originalConfig = await fs.readJSON(configPath);
|
||||
const { dev, port, readyResolver } = await testFixture(dir);
|
||||
|
||||
try {
|
||||
await readyResolver;
|
||||
|
||||
{
|
||||
// Env var should be set from `vercel.json`
|
||||
const res = await fetch(`http://localhost:${port}/api`);
|
||||
const body = await res.json();
|
||||
t.is(body.FOO, 'bar');
|
||||
}
|
||||
|
||||
{
|
||||
// Env var should not be set after `vercel.json` is deleted
|
||||
await fs.remove(configPath);
|
||||
await sleep(1000);
|
||||
|
||||
const res = await fetch(`http://localhost:${port}/api`);
|
||||
const body = await res.json();
|
||||
t.is(body.FOO, undefined);
|
||||
}
|
||||
} finally {
|
||||
await dev.kill('SIGTERM');
|
||||
await fs.writeJSON(configPath, originalConfig);
|
||||
}
|
||||
});
|
||||
|
||||
test('[vercel dev] reflects changes to config and env without restart', async t => {
|
||||
const dir = fixture('node-helpers');
|
||||
const configPath = join(dir, 'vercel.json');
|
||||
const originalConfig = await fs.readJSON(configPath);
|
||||
const { dev, port, readyResolver } = await testFixture(dir);
|
||||
|
||||
try {
|
||||
await readyResolver;
|
||||
|
||||
{
|
||||
// Node.js helpers should be available by default
|
||||
const res = await fetch(`http://localhost:${port}/?foo=bar`);
|
||||
const body = await res.json();
|
||||
t.is(body.hasHelpers, true);
|
||||
t.is(body.query.foo, 'bar');
|
||||
}
|
||||
|
||||
{
|
||||
// Disable the helpers via `config.helpers = false`
|
||||
const config = {
|
||||
...originalConfig,
|
||||
builds: [
|
||||
{
|
||||
...originalConfig.builds[0],
|
||||
config: {
|
||||
helpers: false,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
await fs.writeJSON(configPath, config);
|
||||
await sleep(1000);
|
||||
|
||||
const res = await fetch(`http://localhost:${port}/?foo=bar`);
|
||||
const body = await res.json();
|
||||
t.is(body.hasHelpers, false);
|
||||
t.is(body.query, undefined);
|
||||
}
|
||||
|
||||
{
|
||||
// Enable the helpers via `config.helpers = true`
|
||||
const config = {
|
||||
...originalConfig,
|
||||
builds: [
|
||||
{
|
||||
...originalConfig.builds[0],
|
||||
config: {
|
||||
helpers: true,
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
await fs.writeJSON(configPath, config);
|
||||
await sleep(1000);
|
||||
|
||||
const res = await fetch(`http://localhost:${port}/?foo=baz`);
|
||||
const body = await res.json();
|
||||
t.is(body.hasHelpers, true);
|
||||
t.is(body.query.foo, 'baz');
|
||||
}
|
||||
|
||||
{
|
||||
// Disable the helpers via `NODEJS_HELPERS = '0'`
|
||||
const config = {
|
||||
...originalConfig,
|
||||
build: {
|
||||
env: {
|
||||
NODEJS_HELPERS: '0',
|
||||
},
|
||||
},
|
||||
};
|
||||
await fs.writeJSON(configPath, config);
|
||||
await sleep(1000);
|
||||
|
||||
const res = await fetch(`http://localhost:${port}/?foo=baz`);
|
||||
const body = await res.json();
|
||||
t.is(body.hasHelpers, false);
|
||||
t.is(body.query, undefined);
|
||||
}
|
||||
|
||||
{
|
||||
// Enable the helpers via `NODEJS_HELPERS = '1'`
|
||||
const config = {
|
||||
...originalConfig,
|
||||
build: {
|
||||
env: {
|
||||
NODEJS_HELPERS: '1',
|
||||
},
|
||||
},
|
||||
};
|
||||
await fs.writeJSON(configPath, config);
|
||||
await sleep(1000);
|
||||
|
||||
const res = await fetch(`http://localhost:${port}/?foo=boo`);
|
||||
const body = await res.json();
|
||||
t.is(body.hasHelpers, true);
|
||||
t.is(body.query.foo, 'boo');
|
||||
}
|
||||
} finally {
|
||||
await dev.kill('SIGTERM');
|
||||
await fs.writeJSON(configPath, originalConfig);
|
||||
}
|
||||
});
|
||||
|
||||
test(
|
||||
'[vercel dev] validate routes that use `check: true`',
|
||||
testFixtureStdio('routes-check-true', async testPath => {
|
||||
@@ -482,19 +633,15 @@ test(
|
||||
|
||||
test(
|
||||
'[vercel dev] should serve the public directory and api functions',
|
||||
testFixtureStdio(
|
||||
'public-and-api',
|
||||
async testPath => {
|
||||
await testPath(200, '/', 'This is the home page');
|
||||
await testPath(200, '/about.html', 'This is the about page');
|
||||
await testPath(200, '/api/date', /current date/);
|
||||
await testPath(200, '/api/rand', /random number/);
|
||||
await testPath(200, '/api/rand.js', /random number/);
|
||||
await testPath(404, '/api/api', /NOT_FOUND/m);
|
||||
await testPath(404, '/nothing', /Custom 404 Page/);
|
||||
},
|
||||
{ skipDeploy: true /** TODO: remove after prod goes live */ }
|
||||
)
|
||||
testFixtureStdio('public-and-api', async testPath => {
|
||||
await testPath(200, '/', 'This is the home page');
|
||||
await testPath(200, '/about.html', 'This is the about page');
|
||||
await testPath(200, '/api/date', /current date/);
|
||||
await testPath(200, '/api/rand', /random number/);
|
||||
await testPath(200, '/api/rand.js', /random number/);
|
||||
await testPath(404, '/api/api', /NOT_FOUND/m);
|
||||
await testPath(404, '/nothing', /Custom 404 Page/);
|
||||
})
|
||||
);
|
||||
|
||||
test(
|
||||
@@ -694,17 +841,13 @@ test(
|
||||
|
||||
test(
|
||||
'[vercel dev] should serve custom 404 when `cleanUrls: true`',
|
||||
testFixtureStdio(
|
||||
'test-clean-urls-custom-404',
|
||||
async testPath => {
|
||||
await testPath(200, '/', 'This is the home page');
|
||||
await testPath(200, '/about', 'The about page');
|
||||
await testPath(200, '/contact/me', 'Contact Me Subdirectory');
|
||||
await testPath(404, '/nothing', 'Custom 404 Page');
|
||||
await testPath(404, '/nothing/', 'Custom 404 Page');
|
||||
},
|
||||
{ skipDeploy: true /** TODO: remove after prod goes live */ }
|
||||
)
|
||||
testFixtureStdio('test-clean-urls-custom-404', async testPath => {
|
||||
await testPath(200, '/', 'This is the home page');
|
||||
await testPath(200, '/about', 'The about page');
|
||||
await testPath(200, '/contact/me', 'Contact Me Subdirectory');
|
||||
await testPath(404, '/nothing', 'Custom 404 Page');
|
||||
await testPath(404, '/nothing/', 'Custom 404 Page');
|
||||
})
|
||||
);
|
||||
|
||||
test(
|
||||
@@ -777,16 +920,12 @@ test(
|
||||
|
||||
test(
|
||||
'[vercel dev] should serve custom 404 when `trailingSlash: true`',
|
||||
testFixtureStdio(
|
||||
'test-trailing-slash-custom-404',
|
||||
async testPath => {
|
||||
await testPath(200, '/', 'This is the home page');
|
||||
await testPath(200, '/about.html', 'The about page');
|
||||
await testPath(200, '/contact/', 'Contact Subdirectory');
|
||||
await testPath(404, '/nothing/', 'Custom 404 Page');
|
||||
},
|
||||
{ skipDeploy: true /** TODO: remove after prod goes live */ }
|
||||
)
|
||||
testFixtureStdio('test-trailing-slash-custom-404', async testPath => {
|
||||
await testPath(200, '/', 'This is the home page');
|
||||
await testPath(200, '/about.html', 'The about page');
|
||||
await testPath(200, '/contact/', 'Contact Subdirectory');
|
||||
await testPath(404, '/nothing/', 'Custom 404 Page');
|
||||
})
|
||||
);
|
||||
|
||||
test(
|
||||
@@ -1403,6 +1542,23 @@ test(
|
||||
})
|
||||
);
|
||||
|
||||
test(
|
||||
'[vercel dev] Should force `tsc` option "module: commonjs" for `startDevServer()`',
|
||||
testFixtureStdio('force-module-commonjs', async testPath => {
|
||||
await testPath(200, `/`, /Force "module: commonjs" test page/);
|
||||
await testPath(
|
||||
200,
|
||||
`/api`,
|
||||
'Force "module: commonjs" JavaScript with ES Modules API endpoint'
|
||||
);
|
||||
await testPath(
|
||||
200,
|
||||
`/api/ts`,
|
||||
'Force "module: commonjs" TypeScript API endpoint'
|
||||
);
|
||||
})
|
||||
);
|
||||
|
||||
test(
|
||||
'[vercel dev] should prioritize index.html over other file named index.*',
|
||||
testFixtureStdio('index-html-priority', async testPath => {
|
||||
|
||||
20
packages/now-cli/test/integration.js
vendored
20
packages/now-cli/test/integration.js
vendored
@@ -1589,7 +1589,7 @@ test('create a staging deployment', async t => {
|
||||
/Setting target to staging/gm,
|
||||
formatOutput(targetCall)
|
||||
);
|
||||
|
||||
t.regex(targetCall.stdout, /https:\/\//gm);
|
||||
t.is(targetCall.exitCode, 0, formatOutput(targetCall));
|
||||
|
||||
const { host } = new URL(targetCall.stdout);
|
||||
@@ -1625,6 +1625,7 @@ test('create a production deployment', async t => {
|
||||
/Setting target to production/gm,
|
||||
formatOutput(targetCall)
|
||||
);
|
||||
t.regex(targetCall.stdout, /https:\/\//gm);
|
||||
|
||||
const { host: targetHost } = new URL(targetCall.stdout);
|
||||
const targetDeployment = await apiFetch(
|
||||
@@ -1648,6 +1649,7 @@ test('create a production deployment', async t => {
|
||||
/Setting target to production/gm,
|
||||
formatOutput(targetCall)
|
||||
);
|
||||
t.regex(call.stdout, /https:\/\//gm);
|
||||
|
||||
const { host } = new URL(call.stdout);
|
||||
const deployment = await apiFetch(
|
||||
@@ -2916,3 +2918,19 @@ test('reject conflicting `vercel.json` and `now.json` files', async t => {
|
||||
formatOutput({ stderr, stdout })
|
||||
);
|
||||
});
|
||||
|
||||
test('`vc --debug project ls` should output the projects listing', async t => {
|
||||
const { exitCode, stderr, stdout } = await execa(
|
||||
binaryPath,
|
||||
[...defaultArgs, '--debug', 'project', 'ls'],
|
||||
{
|
||||
reject: false,
|
||||
}
|
||||
);
|
||||
|
||||
t.is(exitCode, 0, formatOutput({ stderr, stdout }));
|
||||
t.true(
|
||||
stdout.includes('> Projects found under'),
|
||||
formatOutput({ stderr, stdout })
|
||||
);
|
||||
});
|
||||
|
||||
4
packages/now-client/.gitignore
vendored
4
packages/now-client/.gitignore
vendored
@@ -3,4 +3,6 @@ lib
|
||||
node_modules
|
||||
*.log
|
||||
|
||||
!tests/fixtures/nowignore/node_modules
|
||||
!tests/fixtures/nowignore/node_modules
|
||||
!tests/fixtures/vercelignore-allow-nodemodules/node_modules
|
||||
!tests/fixtures/vercelignore-allow-nodemodules/sub/node_modules
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/client",
|
||||
"version": "8.0.2-canary.2",
|
||||
"version": "8.1.0",
|
||||
"main": "dist/index.js",
|
||||
"typings": "dist/index.d.ts",
|
||||
"homepage": "https://vercel.com",
|
||||
|
||||
@@ -93,6 +93,16 @@ export async function* checkDeploymentStatus(
|
||||
}
|
||||
|
||||
if (isAliasAssigned(deploymentUpdate)) {
|
||||
if (
|
||||
deploymentUpdate.aliasWarning &&
|
||||
deploymentUpdate.aliasWarning.message
|
||||
) {
|
||||
yield {
|
||||
type: 'warning',
|
||||
payload: deploymentUpdate.aliasWarning.message,
|
||||
};
|
||||
}
|
||||
|
||||
debug('Deployment alias assigned');
|
||||
return yield { type: 'alias-assigned', payload: deploymentUpdate };
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import qs from 'querystring';
|
||||
import ignore from 'ignore';
|
||||
type Ignore = ReturnType<typeof ignore>;
|
||||
import { pkgVersion } from '../pkg';
|
||||
import { NowBuildError } from '@vercel/build-utils';
|
||||
import { NowClientOptions, DeploymentOptions, NowConfig } from '../types';
|
||||
import { Sema } from 'async-sema';
|
||||
import { readFile } from 'fs-extra';
|
||||
@@ -48,7 +49,7 @@ export function getApiDeploymentsUrl(
|
||||
return '/v10/now/deployments';
|
||||
}
|
||||
|
||||
return '/v12/now/deployments';
|
||||
return '/v13/now/deployments';
|
||||
}
|
||||
|
||||
export async function parseVercelConfig(filePath?: string): Promise<NowConfig> {
|
||||
@@ -76,43 +77,22 @@ const maybeRead = async function<T>(path: string, default_: T) {
|
||||
}
|
||||
};
|
||||
|
||||
export async function readdirRelative(
|
||||
path: string,
|
||||
ignores: string[],
|
||||
cwd: string
|
||||
): Promise<string[]> {
|
||||
const preprocessedIgnores = ignores.map(ignore => {
|
||||
if (ignore.endsWith('/')) {
|
||||
return ignore.slice(0, -1);
|
||||
}
|
||||
return ignore;
|
||||
});
|
||||
const dirContents = await readdir(path, preprocessedIgnores);
|
||||
return dirContents.map(filePath => relative(cwd, filePath));
|
||||
}
|
||||
|
||||
export async function buildFileTree(
|
||||
path: string | string[],
|
||||
isDirectory: boolean,
|
||||
debug: Debug
|
||||
): Promise<string[]> {
|
||||
// Get .nowignore
|
||||
let { ig, ignores } = await getVercelIgnore(path);
|
||||
|
||||
debug(`Found ${ig.ignores.length} rules in .nowignore`);
|
||||
|
||||
let fileList: string[];
|
||||
let { ig } = await getVercelIgnore(path);
|
||||
|
||||
debug(`Found ${ig.ignores.length} rules in .vercelignore`);
|
||||
debug('Building file tree...');
|
||||
|
||||
if (isDirectory && !Array.isArray(path)) {
|
||||
// Directory path
|
||||
const cwd = process.cwd();
|
||||
const relativeFileList = await readdirRelative(path, ignores, cwd);
|
||||
fileList = ig
|
||||
.filter(relativeFileList)
|
||||
.map((relativePath: string) => join(cwd, relativePath));
|
||||
|
||||
const ignores = (absPath: string) => ig.ignores(relative(cwd, absPath));
|
||||
fileList = await readdir(path, [ignores]);
|
||||
debug(`Read ${fileList.length} files in the specified directory`);
|
||||
} else if (Array.isArray(path)) {
|
||||
// Array of file paths
|
||||
@@ -166,9 +146,12 @@ export async function getVercelIgnore(
|
||||
maybeRead(join(cwd, '.nowignore'), ''),
|
||||
]);
|
||||
if (vercelignore && nowignore) {
|
||||
throw new Error(
|
||||
'Cannot use both a `.vercelignore` and `.nowignore` file. Please delete the `.nowignore` file.'
|
||||
);
|
||||
throw new NowBuildError({
|
||||
code: 'CONFLICTING_IGNORE_FILES',
|
||||
message:
|
||||
'Cannot use both a `.vercelignore` and `.nowignore` file. Please delete the `.nowignore` file.',
|
||||
link: 'https://vercel.link/combining-old-and-new-config',
|
||||
});
|
||||
}
|
||||
return vercelignore || nowignore;
|
||||
})
|
||||
|
||||
1
packages/now-client/tests/fixtures/vercelignore-allow-nodemodules/.env.local
vendored
Normal file
1
packages/now-client/tests/fixtures/vercelignore-allow-nodemodules/.env.local
vendored
Normal file
@@ -0,0 +1 @@
|
||||
EXCLUDE="this file should be ignored"
|
||||
6
packages/now-client/tests/fixtures/vercelignore-allow-nodemodules/.vercelignore
vendored
Normal file
6
packages/now-client/tests/fixtures/vercelignore-allow-nodemodules/.vercelignore
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
# literally dont ignore the node_modules directory
|
||||
# so basically include the node_modules directory recursively
|
||||
!node_modules/
|
||||
|
||||
# ignore this file in addition to the defaults
|
||||
exclude.txt
|
||||
1
packages/now-client/tests/fixtures/vercelignore-allow-nodemodules/exclude.txt
vendored
Normal file
1
packages/now-client/tests/fixtures/vercelignore-allow-nodemodules/exclude.txt
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Should be ignored
|
||||
1
packages/now-client/tests/fixtures/vercelignore-allow-nodemodules/hello.txt
vendored
Normal file
1
packages/now-client/tests/fixtures/vercelignore-allow-nodemodules/hello.txt
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Hello World
|
||||
0
packages/now-client/tests/fixtures/vercelignore-allow-nodemodules/node_modules/one.txt
generated
vendored
Normal file
0
packages/now-client/tests/fixtures/vercelignore-allow-nodemodules/node_modules/one.txt
generated
vendored
Normal file
1
packages/now-client/tests/fixtures/vercelignore-allow-nodemodules/sub/include.txt
vendored
Normal file
1
packages/now-client/tests/fixtures/vercelignore-allow-nodemodules/sub/include.txt
vendored
Normal file
@@ -0,0 +1 @@
|
||||
Should be included
|
||||
0
packages/now-client/tests/fixtures/vercelignore-allow-nodemodules/sub/node_modules/two.txt
generated
vendored
Normal file
0
packages/now-client/tests/fixtures/vercelignore-allow-nodemodules/sub/node_modules/two.txt
generated
vendored
Normal file
@@ -1,7 +1,8 @@
|
||||
import path from 'path';
|
||||
import { buildFileTree, getVercelIgnore, readdirRelative } from '../src/utils';
|
||||
import { join, resolve } from 'path';
|
||||
import { buildFileTree } from '../src/utils';
|
||||
|
||||
const ignoreFixturePath = path.resolve(__dirname, 'fixtures', 'nowignore');
|
||||
const fixture = (name: string) => resolve(__dirname, 'fixtures', name);
|
||||
const noop = () => {};
|
||||
|
||||
const normalizeWindowsPaths = (files: string[]) => {
|
||||
if (process.platform === 'win32') {
|
||||
@@ -10,34 +11,29 @@ const normalizeWindowsPaths = (files: string[]) => {
|
||||
return files;
|
||||
};
|
||||
|
||||
describe('buildFileTree', () => {
|
||||
it('will include the correct files', async () => {
|
||||
const expected = [
|
||||
'tests/fixtures/nowignore/.nowignore',
|
||||
'tests/fixtures/nowignore/index.txt',
|
||||
].map(p => path.join(process.cwd(), p));
|
||||
const actual = await buildFileTree(ignoreFixturePath, true, () => {});
|
||||
expect(normalizeWindowsPaths(expected).sort()).toEqual(
|
||||
normalizeWindowsPaths(actual).sort()
|
||||
);
|
||||
});
|
||||
});
|
||||
const toAbsolutePaths = (cwd: string, files: string[]) =>
|
||||
files.map(p => join(cwd, p));
|
||||
|
||||
describe('readdirRelative', () => {
|
||||
it('will ignore the hardcoded default ignores', async () => {
|
||||
// most importantly, this method should not walk/include node_modules
|
||||
const expected = [
|
||||
'tests/fixtures/nowignore/.nowignore',
|
||||
'tests/fixtures/nowignore/ignore.txt',
|
||||
'tests/fixtures/nowignore/index.txt',
|
||||
'tests/fixtures/nowignore/folder/ignore.txt',
|
||||
];
|
||||
const { ignores } = await getVercelIgnore(ignoreFixturePath);
|
||||
const actual = await readdirRelative(
|
||||
ignoreFixturePath,
|
||||
ignores,
|
||||
process.cwd()
|
||||
describe('buildFileTree', () => {
|
||||
it('should exclude files using `.nowignore` blocklist', async () => {
|
||||
const cwd = fixture('nowignore');
|
||||
const expected = toAbsolutePaths(cwd, ['.nowignore', 'index.txt']);
|
||||
const actual = await buildFileTree(cwd, true, noop);
|
||||
expect(normalizeWindowsPaths(expected).sort()).toEqual(
|
||||
normalizeWindowsPaths(actual).sort()
|
||||
);
|
||||
});
|
||||
|
||||
it('should include the node_modules using `.vercelignore` allowlist', async () => {
|
||||
const cwd = fixture('vercelignore-allow-nodemodules');
|
||||
const expected = toAbsolutePaths(cwd, [
|
||||
'node_modules/one.txt',
|
||||
'sub/node_modules/two.txt',
|
||||
'sub/include.txt',
|
||||
'.vercelignore',
|
||||
'hello.txt',
|
||||
]);
|
||||
const actual = await buildFileTree(cwd, true, noop);
|
||||
expect(normalizeWindowsPaths(expected).sort()).toEqual(
|
||||
normalizeWindowsPaths(actual).sort()
|
||||
);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/go",
|
||||
"version": "1.1.2-canary.2",
|
||||
"version": "1.1.2",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/go",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/next",
|
||||
"version": "2.6.3",
|
||||
"version": "2.6.6",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/next-js",
|
||||
|
||||
@@ -70,7 +70,7 @@ import {
|
||||
syncEnvVars,
|
||||
validateEntrypoint,
|
||||
} from './utils';
|
||||
import findUp from 'find-up';
|
||||
// import findUp from 'find-up';
|
||||
|
||||
interface BuildParamsMeta {
|
||||
isDev: boolean | undefined;
|
||||
@@ -205,30 +205,6 @@ export const build = async ({
|
||||
}> => {
|
||||
validateEntrypoint(entrypoint);
|
||||
|
||||
const nowJsonPath = await findUp(['now.json', 'vercel.json'], {
|
||||
type: 'file',
|
||||
});
|
||||
let hasLegacyRoutes = false;
|
||||
|
||||
if (nowJsonPath) {
|
||||
const nowJsonData = JSON.parse(await readFile(nowJsonPath, 'utf8'));
|
||||
|
||||
if (Array.isArray(nowJsonData.routes) && nowJsonData.routes.length > 0) {
|
||||
hasLegacyRoutes = true;
|
||||
console.warn(
|
||||
`WARNING: your application is being opted out of @vercel/next's optimized lambdas mode due to legacy routes in ${path.basename(
|
||||
nowJsonPath
|
||||
)}. http://err.sh/vercel/vercel/next-legacy-routes-optimized-lambdas`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// default to true but still allow opting out with the config
|
||||
const isSharedLambdas =
|
||||
!hasLegacyRoutes && typeof config.sharedLambdas === 'undefined'
|
||||
? true
|
||||
: !!config.sharedLambdas;
|
||||
|
||||
// Limit for max size each lambda can be, 50 MB if no custom limit
|
||||
const lambdaCompressedByteLimit = config.maxLambdaSize || 50 * 1000 * 1000;
|
||||
|
||||
@@ -253,6 +229,48 @@ export const build = async ({
|
||||
});
|
||||
}
|
||||
|
||||
// let nowJsonPath = Object.keys(files).find(file => {
|
||||
// return file.endsWith('now.json') || file.endsWith('vercel.json')
|
||||
// })
|
||||
|
||||
// if (nowJsonPath) nowJsonPath = files[nowJsonPath].fsPath
|
||||
|
||||
// if (!nowJsonPath) {
|
||||
// nowJsonPath = await findUp(['now.json', 'vercel.json'], {
|
||||
// cwd: path.join(workPath, path.dirname(entrypoint))
|
||||
// })
|
||||
// }
|
||||
|
||||
// let hasLegacyRoutes = false;
|
||||
// const hasFunctionsConfig = !!config.functions;
|
||||
|
||||
// if (nowJsonPath) {
|
||||
// const nowJsonData = JSON.parse(await readFile(nowJsonPath, 'utf8'));
|
||||
|
||||
// if (Array.isArray(nowJsonData.routes) && nowJsonData.routes.length > 0) {
|
||||
// hasLegacyRoutes = true;
|
||||
// console.warn(
|
||||
// `WARNING: your application is being opted out of @vercel/next's optimized lambdas mode due to legacy routes in ${path.basename(
|
||||
// nowJsonPath
|
||||
// )}. http://err.sh/vercel/vercel/next-legacy-routes-optimized-lambdas`
|
||||
// );
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (hasFunctionsConfig) {
|
||||
// console.warn(
|
||||
// `WARNING: Your application is being opted out of "@vercel/next" optimized lambdas mode due to \`functions\` config.\nMore info: http://err.sh/vercel/vercel/next-functions-config-optimized-lambdas`
|
||||
// );
|
||||
// }
|
||||
|
||||
// default to true but still allow opting out with the config
|
||||
const isSharedLambdas = !!config.sharedLambdas;
|
||||
// !hasLegacyRoutes &&
|
||||
// !hasFunctionsConfig &&
|
||||
// typeof config.sharedLambdas === 'undefined'
|
||||
// ? true
|
||||
// : !!config.sharedLambdas;
|
||||
|
||||
if (meta.isDev) {
|
||||
let childProcess: ChildProcess | undefined;
|
||||
|
||||
@@ -1178,50 +1196,6 @@ export const build = async ({
|
||||
);
|
||||
|
||||
if (isSharedLambdas) {
|
||||
// since we combine the pages into lambda groups we need to merge
|
||||
// the lambda options into one this means they should only configure
|
||||
// lambda options for one page or one API as doing it for
|
||||
// another will override it
|
||||
const getMergedLambdaOptions = async (pageKeys: string[]) => {
|
||||
if (pageKeys.length === 0) return {};
|
||||
|
||||
const lambdaOptions = await getLambdaOptionsFromFunction({
|
||||
sourceFile: await getSourceFilePathFromPage({
|
||||
workPath,
|
||||
page: pageKeys[0],
|
||||
}),
|
||||
config,
|
||||
});
|
||||
|
||||
for (const page of pageKeys) {
|
||||
if (page === pageKeys[0]) continue;
|
||||
const sourceFile = await getSourceFilePathFromPage({
|
||||
workPath,
|
||||
page,
|
||||
});
|
||||
const newOptions = await getLambdaOptionsFromFunction({
|
||||
sourceFile,
|
||||
config,
|
||||
});
|
||||
|
||||
for (const key of Object.keys(newOptions)) {
|
||||
// eslint-disable-next-line
|
||||
if (typeof (newOptions as any)[key] !== 'undefined') {
|
||||
// eslint-disable-next-line
|
||||
(lambdaOptions as any)[key] = (newOptions as any)[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
return lambdaOptions;
|
||||
};
|
||||
|
||||
const mergedPageLambdaOptions = await getMergedLambdaOptions(
|
||||
pageKeys.filter(page => !page.startsWith('api/'))
|
||||
);
|
||||
const mergedApiLambdaOptions = await getMergedLambdaOptions(
|
||||
pageKeys.filter(page => page.startsWith('api/'))
|
||||
);
|
||||
|
||||
const launcherPath = path.join(__dirname, 'templated-launcher-shared.js');
|
||||
const launcherData = await readFile(launcherPath, 'utf8');
|
||||
|
||||
@@ -1337,9 +1311,6 @@ export const build = async ({
|
||||
],
|
||||
handler: 'now__launcher.launcher',
|
||||
runtime: nodeVersion.runtime,
|
||||
...(group.isApiLambda
|
||||
? mergedApiLambdaOptions
|
||||
: mergedPageLambdaOptions),
|
||||
});
|
||||
} else {
|
||||
lambdas[
|
||||
@@ -1352,9 +1323,6 @@ export const build = async ({
|
||||
layers: pageLayers,
|
||||
handler: 'now__launcher.launcher',
|
||||
runtime: nodeVersion.runtime,
|
||||
...(group.isApiLambda
|
||||
? mergedApiLambdaOptions
|
||||
: mergedPageLambdaOptions),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,8 +15,8 @@ it(
|
||||
buildResult: { output },
|
||||
} = await runBuildLambda(path.join(__dirname, 'standard'));
|
||||
expect(output['index']).toBeDefined();
|
||||
expect(output.goodbye).not.toBeDefined();
|
||||
expect(output.__NEXT_PAGE_LAMBDA_0).toBeDefined();
|
||||
expect(output.goodbye).toBeDefined();
|
||||
expect(output.__NEXT_PAGE_LAMBDA_0).not.toBeDefined();
|
||||
const filePaths = Object.keys(output);
|
||||
const serverlessError = filePaths.some(filePath =>
|
||||
filePath.match(/_error/)
|
||||
@@ -34,6 +34,28 @@ it(
|
||||
FOUR_MINUTES
|
||||
);
|
||||
|
||||
// it(
|
||||
// 'Should opt-out of shared lambdas when routes are detected',
|
||||
// async () => {
|
||||
// const {
|
||||
// buildResult: { output },
|
||||
// } = await runBuildLambda(path.join(__dirname, '../fixtures/26-mono-repo-404-lambda'));
|
||||
// expect(output['packages/webapp/404']).toBeDefined();
|
||||
// expect(output['packages/webapp/index']).toBeDefined();
|
||||
// expect(output['packages/webapp/__NEXT_PAGE_LAMBDA_0']).not.toBeDefined();
|
||||
// const filePaths = Object.keys(output);
|
||||
// const hasUnderScoreAppStaticFile = filePaths.some(filePath =>
|
||||
// filePath.match(/static.*\/pages\/_app\.js$/)
|
||||
// );
|
||||
// const hasUnderScoreErrorStaticFile = filePaths.some(filePath =>
|
||||
// filePath.match(/static.*\/pages\/_error\.js$/)
|
||||
// );
|
||||
// expect(hasUnderScoreAppStaticFile).toBeTruthy();
|
||||
// expect(hasUnderScoreErrorStaticFile).toBeTruthy();
|
||||
// },
|
||||
// FOUR_MINUTES
|
||||
// );
|
||||
|
||||
it(
|
||||
'Should build the monorepo example',
|
||||
async () => {
|
||||
@@ -41,8 +63,8 @@ it(
|
||||
buildResult: { output },
|
||||
} = await runBuildLambda(path.join(__dirname, 'monorepo'));
|
||||
|
||||
expect(output['www/index']).not.toBeDefined();
|
||||
expect(output['www/__NEXT_PAGE_LAMBDA_0']).toBeDefined();
|
||||
expect(output['www/index']).toBeDefined();
|
||||
expect(output['www/__NEXT_PAGE_LAMBDA_0']).not.toBeDefined();
|
||||
expect(output['www/static/test.txt']).toBeDefined();
|
||||
expect(output['www/data.txt']).toBeDefined();
|
||||
const filePaths = Object.keys(output);
|
||||
@@ -142,9 +164,9 @@ it(
|
||||
buildResult: { output },
|
||||
} = await runBuildLambda(path.join(__dirname, 'serverless-config'));
|
||||
|
||||
expect(output.index).not.toBeDefined();
|
||||
expect(output.goodbye).not.toBeDefined();
|
||||
expect(output.__NEXT_PAGE_LAMBDA_0).toBeDefined();
|
||||
expect(output.index).toBeDefined();
|
||||
expect(output.goodbye).toBeDefined();
|
||||
expect(output.__NEXT_PAGE_LAMBDA_0).not.toBeDefined();
|
||||
const filePaths = Object.keys(output);
|
||||
const serverlessError = filePaths.some(filePath =>
|
||||
filePath.match(/_error/)
|
||||
@@ -179,9 +201,9 @@ it(
|
||||
path.join(__dirname, 'serverless-config-monorepo-missing')
|
||||
);
|
||||
|
||||
expect(output['nested/index']).not.toBeDefined();
|
||||
expect(output['nested/goodbye']).not.toBeDefined();
|
||||
expect(output['nested/__NEXT_PAGE_LAMBDA_0']).toBeDefined();
|
||||
expect(output['nested/index']).toBeDefined();
|
||||
expect(output['nested/goodbye']).toBeDefined();
|
||||
expect(output['nested/__NEXT_PAGE_LAMBDA_0']).not.toBeDefined();
|
||||
const filePaths = Object.keys(output);
|
||||
const serverlessError = filePaths.some(filePath =>
|
||||
filePath.match(/_error/)
|
||||
@@ -213,9 +235,9 @@ it(
|
||||
path.join(__dirname, 'serverless-config-monorepo-present')
|
||||
);
|
||||
|
||||
expect(output['nested/index']).not.toBeDefined();
|
||||
expect(output['nested/goodbye']).not.toBeDefined();
|
||||
expect(output['nested/__NEXT_PAGE_LAMBDA_0']).toBeDefined();
|
||||
expect(output['nested/index']).toBeDefined();
|
||||
expect(output['nested/goodbye']).toBeDefined();
|
||||
expect(output['nested/__NEXT_PAGE_LAMBDA_0']).not.toBeDefined();
|
||||
const filePaths = Object.keys(output);
|
||||
const serverlessError = filePaths.some(filePath =>
|
||||
filePath.match(/_error/)
|
||||
@@ -281,8 +303,8 @@ it(
|
||||
} = await runBuildLambda(path.join(__dirname, 'serverless-config-object'));
|
||||
|
||||
expect(output['index']).toBeDefined();
|
||||
expect(output.goodbye).not.toBeDefined();
|
||||
expect(output.__NEXT_PAGE_LAMBDA_0).toBeDefined();
|
||||
expect(output.goodbye).toBeDefined();
|
||||
expect(output.__NEXT_PAGE_LAMBDA_0).not.toBeDefined();
|
||||
const filePaths = Object.keys(output);
|
||||
const serverlessError = filePaths.some(filePath =>
|
||||
filePath.match(/_error/)
|
||||
@@ -316,8 +338,8 @@ it(
|
||||
} = await runBuildLambda(path.join(__dirname, 'serverless-no-config'));
|
||||
|
||||
expect(output['index']).toBeDefined();
|
||||
expect(output.goodbye).not.toBeDefined();
|
||||
expect(output.__NEXT_PAGE_LAMBDA_0).toBeDefined();
|
||||
expect(output.goodbye).toBeDefined();
|
||||
expect(output.__NEXT_PAGE_LAMBDA_0).not.toBeDefined();
|
||||
const filePaths = Object.keys(output);
|
||||
const serverlessError = filePaths.some(filePath =>
|
||||
filePath.match(/_error/)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/node-bridge",
|
||||
"version": "1.3.1-canary.2",
|
||||
"version": "1.3.1",
|
||||
"license": "MIT",
|
||||
"main": "./index.js",
|
||||
"repository": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/node",
|
||||
"version": "1.6.2-canary.5",
|
||||
"version": "1.7.0",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/node-js",
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
const entrypoint = process.env.NOW_DEV_ENTRYPOINT;
|
||||
delete process.env.NOW_DEV_ENTRYPOINT;
|
||||
const entrypoint = process.env.VERCEL_DEV_ENTRYPOINT;
|
||||
delete process.env.VERCEL_DEV_ENTRYPOINT;
|
||||
|
||||
const tsconfig = process.env.NOW_DEV_TSCONFIG;
|
||||
delete process.env.NOW_DEV_TSCONFIG;
|
||||
const tsconfig = process.env.VERCEL_DEV_TSCONFIG;
|
||||
delete process.env.VERCEL_DEV_TSCONFIG;
|
||||
|
||||
if (!entrypoint) {
|
||||
throw new Error('`NOW_DEV_ENTRYPOINT` must be defined');
|
||||
throw new Error('`VERCEL_DEV_ENTRYPOINT` must be defined');
|
||||
}
|
||||
|
||||
import { register } from 'ts-node';
|
||||
@@ -27,6 +27,7 @@ register({
|
||||
allowJs: true,
|
||||
esModuleInterop: true,
|
||||
jsx: 'react',
|
||||
module: 'commonjs',
|
||||
},
|
||||
project: tsconfig || undefined, // Resolve `tsconfig.json` from entrypoint dir
|
||||
transpileOnly: true,
|
||||
@@ -49,11 +50,14 @@ function listen(server: Server, port: number, host: string): Promise<void> {
|
||||
let bridge: Bridge | undefined = undefined;
|
||||
|
||||
async function main() {
|
||||
const config = JSON.parse(process.env.NOW_DEV_CONFIG || '{}');
|
||||
delete process.env.NOW_DEV_CONFIG;
|
||||
const config = JSON.parse(process.env.VERCEL_DEV_CONFIG || '{}');
|
||||
delete process.env.VERCEL_DEV_CONFIG;
|
||||
|
||||
const buildEnv = JSON.parse(process.env.VERCEL_DEV_BUILD_ENV || '{}');
|
||||
delete process.env.VERCEL_DEV_BUILD_ENV;
|
||||
|
||||
const shouldAddHelpers = !(
|
||||
config.helpers === false || process.env.NODEJS_HELPERS === '0'
|
||||
config.helpers === false || buildEnv.NODEJS_HELPERS === '0'
|
||||
);
|
||||
|
||||
bridge = getNowLauncher({
|
||||
|
||||
@@ -445,9 +445,10 @@ export async function startDevServer(
|
||||
env: {
|
||||
...process.env,
|
||||
...meta.env,
|
||||
NOW_DEV_ENTRYPOINT: entrypoint,
|
||||
NOW_DEV_TSCONFIG: projectTsConfig || '',
|
||||
NOW_DEV_CONFIG: JSON.stringify(config),
|
||||
VERCEL_DEV_ENTRYPOINT: entrypoint,
|
||||
VERCEL_DEV_TSCONFIG: projectTsConfig || '',
|
||||
VERCEL_DEV_CONFIG: JSON.stringify(config),
|
||||
VERCEL_DEV_BUILD_ENV: JSON.stringify(meta.buildEnv || {}),
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/python",
|
||||
"version": "1.2.2-canary.2",
|
||||
"version": "1.2.2",
|
||||
"main": "./dist/index.js",
|
||||
"license": "MIT",
|
||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/python",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/routing-utils",
|
||||
"version": "1.8.3-canary.5",
|
||||
"version": "1.8.3",
|
||||
"description": "Vercel routing utilities",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
|
||||
@@ -230,6 +230,7 @@ function createError(
|
||||
const errors = Array.isArray(allErrors) ? allErrors : [allErrors];
|
||||
const message = errors[0];
|
||||
const error: RouteApiError = {
|
||||
name: 'RouteApiError',
|
||||
code,
|
||||
message,
|
||||
link,
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { HandleValue } from './index';
|
||||
|
||||
export type RouteApiError = {
|
||||
name: string;
|
||||
code: string;
|
||||
message: string;
|
||||
link?: string; // link to error message details
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@vercel/ruby",
|
||||
"author": "Nathan Cahill <nathan@nathancahill.com>",
|
||||
"version": "1.2.2-canary.1",
|
||||
"version": "1.2.2",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/ruby",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/static-build",
|
||||
"version": "0.17.2-canary.1",
|
||||
"version": "0.17.2",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/static-builds",
|
||||
|
||||
@@ -186,7 +186,10 @@ async function fetchTokenWithRetry(retries = 5) {
|
||||
},
|
||||
});
|
||||
if (!res.ok) {
|
||||
throw new Error(`Unexpected status from registration: ${res.status}`);
|
||||
const text = await res.text();
|
||||
throw new Error(
|
||||
`Unexpected status (${res.status}) from registration: ${text}`
|
||||
);
|
||||
}
|
||||
const data = await res.json();
|
||||
if (!data) {
|
||||
|
||||
103
yarn.lock
103
yarn.lock
@@ -1402,9 +1402,9 @@
|
||||
"@types/node" ">= 8"
|
||||
|
||||
"@octokit/types@^4.0.1":
|
||||
version "4.1.5"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/types/-/types-4.1.5.tgz#465872f9f5f5e6bb85c6ed763053486bba9b251b"
|
||||
integrity sha512-/MKeipxtwMorckj1bfP+SKhbzKhqQimT5JuXKGtwnLazqDwj/noYYSPChpLzstVAwF8JVPygJ7L75cKCK47Ikg==
|
||||
version "4.1.9"
|
||||
resolved "https://registry.yarnpkg.com/@octokit/types/-/types-4.1.9.tgz#a3e1ff1a15637ab830fbab0268c2d7ca824bc969"
|
||||
integrity sha512-hinM/BA2c1vebN2HSR3JtVdYtrSbmvn/doUBZXXuQuh/9o60hYwitQQAGTpJu+k6pjtjURskDHQxUFvqLvYCeA==
|
||||
dependencies:
|
||||
"@types/node" ">= 8"
|
||||
|
||||
@@ -1485,9 +1485,9 @@
|
||||
escape-string-regexp "^2.0.0"
|
||||
|
||||
"@sindresorhus/transliterate@^0.1.0":
|
||||
version "0.1.0"
|
||||
resolved "https://registry.yarnpkg.com/@sindresorhus/transliterate/-/transliterate-0.1.0.tgz#c063bfc4102783fb19c91c2f8c1efb3adfb754be"
|
||||
integrity sha512-bO6v0M0EuJPjm5Ntfow4nk+r3EZQ41n0ahvAmh766FzPqlm6V/2uDc01vZI3gLeI/1lgV2BTMb6QvxOk9z73ng==
|
||||
version "0.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@sindresorhus/transliterate/-/transliterate-0.1.1.tgz#779b31244781d3c898f185b61d58c89e7c782674"
|
||||
integrity sha512-QSdIQ5keUFAZ3KLbfbsntW39ox0Ym8183RqTwBq/ZEFoN3NQAtGV+qWaNdzKpIDHgj9J2CQ2iNDRVU11Zyr7MQ==
|
||||
dependencies:
|
||||
escape-string-regexp "^2.0.0"
|
||||
lodash.deburr "^4.1.0"
|
||||
@@ -1731,7 +1731,7 @@
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/glob@7.1.1", "@types/glob@^7.1.1":
|
||||
"@types/glob@7.1.1":
|
||||
version "7.1.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.1.tgz#aa59a1c6e3fbc421e07ccd31a944c30eba521575"
|
||||
integrity sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==
|
||||
@@ -1740,6 +1740,14 @@
|
||||
"@types/minimatch" "*"
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/glob@^7.1.1":
|
||||
version "7.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.2.tgz#06ca26521353a545d94a0adc74f38a59d232c987"
|
||||
integrity sha512-VgNIkxK+j7Nz5P7jvUZlRvhuPSmsEfS03b0alKcq5V/STUKAa3Plemsn5mrQUO7am6OErJ4rhGEGJbACclrtRA==
|
||||
dependencies:
|
||||
"@types/minimatch" "*"
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/http-proxy@1.16.2":
|
||||
version "1.16.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/http-proxy/-/http-proxy-1.16.2.tgz#16cb373b52fff2aa2f389d23d940ed4a642349e5"
|
||||
@@ -1892,9 +1900,9 @@
|
||||
form-data "^3.0.0"
|
||||
|
||||
"@types/node@*", "@types/node@>= 8":
|
||||
version "14.0.9"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.9.tgz#43896ab87fc82bda1dfd600cdf44a0c8a64e11d2"
|
||||
integrity sha512-0sCTiXKXELOBxvZLN4krQ0FPOAA7ij+6WwvD0k/PHd9/KAkr4dXel5J9fh6F4x1FwAQILqAWkmpeuS6mjf1iKA==
|
||||
version "14.0.12"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.12.tgz#9c1d8ffb8084e8936603a6122a7649e40e68e04b"
|
||||
integrity sha512-/sjzehvjkkpvLpYtN6/2dv5kg41otMGuHQUt9T2aiAuIfleCQRQHXXzF1eAw/qkZTj5Kcf4JSTf7EIizHocy6Q==
|
||||
|
||||
"@types/node@10.12.18":
|
||||
version "10.12.18"
|
||||
@@ -1902,9 +1910,9 @@
|
||||
integrity sha512-fh+pAqt4xRzPfqA6eh3Z2y6fyZavRIumvjhaCL753+TVkGKGhpPeyrJG2JftD0T9q4GF00KjefsQ+PQNDdWQaQ==
|
||||
|
||||
"@types/node@10.x":
|
||||
version "10.17.24"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.24.tgz#c57511e3a19c4b5e9692bb2995c40a3a52167944"
|
||||
integrity sha512-5SCfvCxV74kzR3uWgTYiGxrd69TbT1I6+cMx1A5kEly/IVveJBimtAMlXiEyVFn5DvUFewQWxOOiJhlxeQwxgA==
|
||||
version "10.17.25"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.25.tgz#64f64cd3e8641e8163c81045e545d2825d300e37"
|
||||
integrity sha512-EWPw3jDB0jip4HafDkoezNOwG00TtVZ1TOe74MaxIBWgpyM60UF/LXzFVx9+8AdSYNNOPgx7TuJoRmgnhHZ/7g==
|
||||
|
||||
"@types/node@11.11.0":
|
||||
version "11.11.0"
|
||||
@@ -2429,17 +2437,7 @@ aggregate-error@3.0.1, aggregate-error@^3.0.0:
|
||||
clean-stack "^2.0.0"
|
||||
indent-string "^4.0.0"
|
||||
|
||||
ajv@6.10.2:
|
||||
version "6.10.2"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.10.2.tgz#d3cea04d6b017b2894ad69040fec8b623eb4bd52"
|
||||
integrity sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==
|
||||
dependencies:
|
||||
fast-deep-equal "^2.0.1"
|
||||
fast-json-stable-stringify "^2.0.0"
|
||||
json-schema-traverse "^0.4.1"
|
||||
uri-js "^4.2.2"
|
||||
|
||||
ajv@^6.0.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.5.5:
|
||||
ajv@6.12.2, ajv@^6.0.0, ajv@^6.10.0, ajv@^6.10.2, ajv@^6.5.5:
|
||||
version "6.12.2"
|
||||
resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.12.2.tgz#c629c5eced17baf314437918d2da88c99d5958cd"
|
||||
integrity sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==
|
||||
@@ -4614,9 +4612,9 @@ escape-string-regexp@^2.0.0:
|
||||
integrity sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==
|
||||
|
||||
escodegen@^1.9.1:
|
||||
version "1.14.1"
|
||||
resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.1.tgz#ba01d0c8278b5e95a9a45350142026659027a457"
|
||||
integrity sha512-Bmt7NcRySdIfNPfU2ZoXDrrXsG9ZjvDxcAlMfDUgRBjLOWTuIACXPBFJH7Z+cLb40JeQco5toikyc9t9P8E9SQ==
|
||||
version "1.14.2"
|
||||
resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.2.tgz#14ab71bf5026c2aa08173afba22c6f3173284a84"
|
||||
integrity sha512-InuOIiKk8wwuOFg6x9BQXbzjrQhtyXh46K9bqVTPzSo2FnyMBaYGBMC6PhQy7yxxil9vIedFBweQBMK74/7o8A==
|
||||
dependencies:
|
||||
esprima "^4.0.1"
|
||||
estraverse "^4.2.0"
|
||||
@@ -4648,9 +4646,9 @@ eslint-scope@^4.0.0:
|
||||
estraverse "^4.1.1"
|
||||
|
||||
eslint-scope@^5.0.0:
|
||||
version "5.0.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.0.0.tgz#e87c8887c73e8d1ec84f1ca591645c358bfc8fb9"
|
||||
integrity sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-5.1.0.tgz#d0f971dfe59c69e0cada684b23d49dbf82600ce5"
|
||||
integrity sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==
|
||||
dependencies:
|
||||
esrecurse "^4.1.0"
|
||||
estraverse "^4.1.1"
|
||||
@@ -4670,9 +4668,9 @@ eslint-utils@^2.0.0:
|
||||
eslint-visitor-keys "^1.1.0"
|
||||
|
||||
eslint-visitor-keys@^1.0.0, eslint-visitor-keys@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz#e2a82cea84ff246ad6fb57f9bde5b46621459ec2"
|
||||
integrity sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/eslint-visitor-keys/-/eslint-visitor-keys-1.2.0.tgz#74415ac884874495f78ec2a97349525344c981fa"
|
||||
integrity sha512-WFb4ihckKil6hu3Dp798xdzSfddwKKU3+nGniKF6HfeW6OLd2OUDEPP7TcHtB5+QXOKg2s6B2DaMPE1Nn/kxKQ==
|
||||
|
||||
eslint@6.2.2:
|
||||
version "6.2.2"
|
||||
@@ -4995,15 +4993,10 @@ extsprintf@^1.2.0:
|
||||
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
|
||||
integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=
|
||||
|
||||
fast-deep-equal@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49"
|
||||
integrity sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=
|
||||
|
||||
fast-deep-equal@^3.1.1:
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4"
|
||||
integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA==
|
||||
fast-deep-equal@3.1.3, fast-deep-equal@^3.1.1:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
|
||||
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
|
||||
|
||||
fast-diff@^1.1.2:
|
||||
version "1.2.0"
|
||||
@@ -6506,11 +6499,11 @@ is-promise@^2.1.0:
|
||||
integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==
|
||||
|
||||
is-regex@^1.0.4, is-regex@^1.0.5:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.5.tgz#39d589a358bf18967f726967120b8fc1aed74eae"
|
||||
integrity sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.0.tgz#ece38e389e490df0dc21caea2bd596f987f767ff"
|
||||
integrity sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==
|
||||
dependencies:
|
||||
has "^1.0.3"
|
||||
has-symbols "^1.0.1"
|
||||
|
||||
is-regexp@^1.0.0:
|
||||
version "1.0.0"
|
||||
@@ -7838,9 +7831,9 @@ merge-stream@^2.0.0:
|
||||
integrity sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==
|
||||
|
||||
merge2@^1.2.3, merge2@^1.3.0:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.3.0.tgz#5b366ee83b2f1582c48f87e47cf1a9352103ca81"
|
||||
integrity sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.4.1.tgz#4368892f885e907455a6fd7dc55c0c9d404990ae"
|
||||
integrity sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==
|
||||
|
||||
micro@9.1.2:
|
||||
version "9.1.2"
|
||||
@@ -9536,9 +9529,9 @@ regenerate-unicode-properties@^8.2.0:
|
||||
regenerate "^1.4.0"
|
||||
|
||||
regenerate@^1.4.0:
|
||||
version "1.4.0"
|
||||
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11"
|
||||
integrity sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.1.tgz#cad92ad8e6b591773485fbe05a485caf4f457e6f"
|
||||
integrity sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A==
|
||||
|
||||
regex-not@^1.0.0, regex-not@^1.0.2:
|
||||
version "1.0.2"
|
||||
@@ -11522,9 +11515,9 @@ widest-line@^3.1.0:
|
||||
string-width "^4.0.0"
|
||||
|
||||
windows-release@^3.1.0:
|
||||
version "3.3.0"
|
||||
resolved "https://registry.yarnpkg.com/windows-release/-/windows-release-3.3.0.tgz#dce167e9f8be733f21c849ebd4d03fe66b29b9f0"
|
||||
integrity sha512-2HetyTg1Y+R+rUgrKeUEhAG/ZuOmTrI1NBb3ZyAGQMYmOJjBBPe4MTodghRkmLJZHwkuPi02anbeGP+Zf401LQ==
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/windows-release/-/windows-release-3.3.1.tgz#cb4e80385f8550f709727287bf71035e209c4ace"
|
||||
integrity sha512-Pngk/RDCaI/DkuHPlGTdIkDiTAnAkyMjoQMZqRsxydNl1qGXNIoZrB7RK8g53F2tEgQBMqQJHQdYZuQEEAu54A==
|
||||
dependencies:
|
||||
execa "^1.0.0"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user