Compare commits

...

13 Commits

Author SHA1 Message Date
Nathan Rajlich
4a8504fc45 Publish Stable
- @vercel/build-utils@2.15.1
 - vercel@24.1.0
 - @vercel/client@10.4.1
 - @vercel/frameworks@0.7.1
 - @vercel/go@1.3.2
 - @vercel/node@1.14.1
 - @vercel/python@2.2.2
 - @vercel/redwood@0.7.0
 - @vercel/routing-utils@1.13.1
 - @vercel/ruby@1.3.2
 - @vercel/static-build@0.23.1
2022-04-11 10:14:53 -07:00
Nathan Rajlich
576217b344 [static-build] Fix prepareCache() when deploying with --prebuilt (#7659)
The `prepareCache()` function was throwing an error when doing `vc deploy --prebuilt` because the `package.json` file is not present.

Also just cleaned up the logic a bit.
2022-04-09 20:51:38 +00:00
Steven
f03129ac7a [tests] Bump mkdocs test fixture (#7660)
* [tests] Bump mkdocs test fixture

* Bump pelican
2022-04-09 14:24:26 -04:00
Sean Massa
3eaad1fd52 [cli] remove deprecation warning for vc env (#7654)
Removes the deprecation warning in the CLI for `vc env`. This command will coexist with `vc pull` for a slightly different purpose.
2022-04-08 19:46:11 -04:00
Nathan Rajlich
4e471491d8 [build-utils] Add repoRootPath to PrepareCacheOptions (#7658)
`repoRootPath` is provided to the `prepareCache()` function and is the same value as provided to the `build()` function.

Also remove `cachePath` since it's no longer used.
2022-04-08 20:39:47 +00:00
Sean Massa
99395fd9fe [cli] trim env file path output (#7653) 2022-04-08 13:14:23 -05:00
Sean Massa
4980fe6513 [cli] remove references to vc pull --env-file (#7647) 2022-04-05 13:30:41 -07:00
Sean Massa
24676ae020 [cli] Add --environment to vc pull (#7624)
* refactor in prep for changes

* pull all target env files

* update `pull` usage

* move .env files into /.vercel

* tighten types in helper functions

* add return type

* remove "any" type

* keep original behavior

* only use --env for root-level env file name

* add --target flag

* deprecate --env for --env-file

* rename --target to --environment

* more renaming

* pr feedback

* update `vc pull --help`

* Update pull.ts

* remove env-file logic from `vc pull`

Co-authored-by: Steven <steven@ceriously.com>
2022-04-05 11:08:29 -07:00
Steven
72ada9abd8 [examples] Bump Next.js + React (#7644)
Bump Next.js + React + ESLint
2022-04-04 09:13:20 -04:00
Steven
da893e7c57 [tests] Increase timeout cli tests (#7640)
* [tests] Increase network timeout for GH Actions

* [tests] Increase CLI integration test timeout
2022-04-01 10:52:47 -04:00
Sean Massa
e40eecafc9 [cli] Add support for vc --cwd <dir> (#7577)
`vc`'s default command is `deploy`, which can lead to ambiguous cli invocations when running `vc dir-or-command` like:

```
$  vc list
Vercel CLI 23.1.2
Error! The supplied argument "list" is ambiguous.
If you wish to deploy the subdirectory "list", first run "cd list".
```

when run in a directory that contains a subdirectory "list". This conflict will happen with any current and future commands, like `vc build`.

In order to make sure the CLI can be invoked either way, this PR deprecates the default behavior. Going forward, a user would see the following.

**Conflicting Command, Run Command**

```bash
$ vc list
# warning: Did you mean to deploy the subdirectory "list"? Use `vc --cwd list` instead.
# ... runs the `list` command
```

**Conflicting Command, Deploy Directory**

```bash
$ vc --cwd list
# ... deploy as normal
```

---

Card: https://linear.app/vercel/issue/BUI-33/prevent-ambiguous-vc-command-oror-dir
2022-03-30 21:06:16 +00:00
Steven
d9e5342eba [examples] Fix angular demo url (#7635) 2022-03-30 11:53:42 -05:00
Steven
b0ab13778d [frameworks] Update comments (#7636)
The comments were outdated
2022-03-30 10:14:03 -04:00
41 changed files with 5302 additions and 1820 deletions

View File

@@ -11,7 +11,7 @@ on:
jobs:
test:
name: CLI
timeout-minutes: 30
timeout-minutes: 40
strategy:
fail-fast: false
matrix:

View File

@@ -10,7 +10,7 @@ Deploy your own Angular project with Vercel.
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?repository-url=https://github.com/vercel/vercel/tree/main/examples/angular&template=angular)
_Live Example: https://angular-now-examples.vercel.app_
_Live Example: https://angular-template.vercel.app_
## Development server

4882
examples/nextjs/package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -7,12 +7,12 @@
"lint": "next lint"
},
"dependencies": {
"next": "12.1.0",
"react": "17.0.2",
"react-dom": "17.0.2"
"next": "12.1.4",
"react": "18.0.0",
"react-dom": "18.0.0"
},
"devDependencies": {
"eslint": "8.9.0",
"eslint-config-next": "12.1.0"
"eslint": "8.12.0",
"eslint-config-next": "12.1.4"
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/build-utils",
"version": "2.15.1-canary.0",
"version": "2.15.1",
"license": "MIT",
"main": "./dist/index.js",
"types": "./dist/index.d.js",
@@ -30,7 +30,7 @@
"@types/node-fetch": "^2.1.6",
"@types/semver": "6.0.0",
"@types/yazl": "^2.4.1",
"@vercel/frameworks": "0.7.1-canary.0",
"@vercel/frameworks": "0.7.1",
"@vercel/ncc": "0.24.0",
"aggregate-error": "3.0.1",
"async-retry": "1.2.3",

View File

@@ -119,10 +119,11 @@ export interface PrepareCacheOptions {
workPath: string;
/**
* A writable temporary directory where you can build a cache to use for
* the next run.
* The "Root Directory" is assigned to the `workPath` so the `repoRootPath`
* is the Git Repository Root. This is only relevant for Monorepos.
* See https://vercel.com/blog/monorepos
*/
cachePath: string;
repoRootPath?: string;
/**
* An arbitrary object passed by the user in the build definition defined

View File

@@ -1,6 +1,6 @@
{
"name": "vercel",
"version": "24.0.2-canary.0",
"version": "24.1.0",
"preferGlobal": true,
"license": "Apache-2.0",
"description": "The command-line interface for Vercel",
@@ -43,11 +43,11 @@
"node": ">= 12"
},
"dependencies": {
"@vercel/build-utils": "2.15.1-canary.0",
"@vercel/go": "1.3.2-canary.0",
"@vercel/node": "1.14.1-canary.0",
"@vercel/python": "2.2.2-canary.0",
"@vercel/ruby": "1.3.2-canary.0",
"@vercel/build-utils": "2.15.1",
"@vercel/go": "1.3.2",
"@vercel/node": "1.14.1",
"@vercel/python": "2.2.2",
"@vercel/ruby": "1.3.2",
"update-notifier": "4.1.0"
},
"devDependencies": {
@@ -88,9 +88,9 @@
"@types/update-notifier": "5.1.0",
"@types/which": "1.3.2",
"@types/write-json-file": "2.2.1",
"@vercel/client": "10.4.1-canary.0",
"@vercel/client": "10.4.1",
"@vercel/fetch-retry": "5.0.3",
"@vercel/frameworks": "0.7.1-canary.0",
"@vercel/frameworks": "0.7.1",
"@vercel/ncc": "0.24.0",
"@vercel/nft": "0.17.5",
"@zeit/fun": "0.11.2",

View File

@@ -42,6 +42,7 @@ export const help = () => `
-h, --help Output usage information
-v, --version Output the version number
--cwd Current working directory
-V, --platform-version Set the platform version to deploy to
-A ${chalk.bold.underline('FILE')}, --local-config=${chalk.bold.underline(
'FILE'

View File

@@ -1,4 +1,5 @@
import chalk from 'chalk';
import { ProjectEnvTarget } from '../../types';
import Client from '../../util/client';
import { getEnvTargetPlaceholder } from '../../util/env/env-target';
import getArgs from '../../util/get-args';
@@ -137,14 +138,14 @@ export default async function main(client: Client) {
case 'rm':
return rm(client, project, argv, args, output);
case 'pull':
output.warn(
`${getCommandName(
'env pull'
)} is deprecated and will be removed in future releases. Run ${getCommandName(
'pull'
)} instead.`
return pull(
client,
project,
ProjectEnvTarget.Development,
argv,
args,
output
);
return pull(client, project, argv, args, output);
default:
output.error(getInvalidSubcommand(COMMAND_CONFIG));
help();

View File

@@ -1,7 +1,7 @@
import chalk from 'chalk';
import { closeSync, openSync, promises, readSync } from 'fs';
import { resolve } from 'path';
import { Project } from '../../types';
import { Project, ProjectEnvTarget } from '../../types';
import Client from '../../util/client';
import exposeSystemEnvs from '../../util/dev/expose-system-envs';
import { emoji, prependEmoji } from '../../util/emoji';
@@ -45,9 +45,11 @@ function tryReadHeadSync(path: string, length: number) {
export default async function pull(
client: Client,
project: Project,
environment: ProjectEnvTarget,
opts: Partial<Options>,
args: string[],
output: Output
output: Output,
cwd: string = process.cwd()
) {
if (args.length > 1) {
output.error(
@@ -58,7 +60,7 @@ export default async function pull(
// handle relative or absolute filename
const [filename = '.env'] = args;
const fullPath = resolve(filename);
const fullPath = resolve(cwd, filename);
const skipConfirmation = opts['--yes'];
const head = tryReadHeadSync(fullPath, Buffer.byteLength(CONTENTS_PREFIX));
@@ -88,7 +90,7 @@ export default async function pull(
output.spinner('Downloading');
const [{ envs: projectEnvs }, { systemEnvValues }] = await Promise.all([
getDecryptedEnvRecords(output, client, project.id),
getDecryptedEnvRecords(output, client, project.id, environment),
project.autoExposeSystemEnvs
? getSystemEnvValues(output, client, project.id)
: { systemEnvValues: [] },

View File

@@ -1,6 +1,7 @@
import chalk from 'chalk';
import { join } from 'path';
import Client from '../util/client';
import { ProjectEnvTarget } from '../types';
import { emoji, prependEmoji } from '../util/emoji';
import getArgs from '../util/get-args';
import handleError from '../util/handle-error';
@@ -14,7 +15,13 @@ import {
VERCEL_DIR_PROJECT,
} from '../util/projects/link';
import { writeProjectSettings } from '../util/projects/project-settings';
import pull from './env/pull';
import envPull from './env/pull';
import type { Project, Org } from '../types';
import {
isValidEnvTarget,
getEnvTargetPlaceholder,
} from '../util/env/env-target';
const help = () => {
return console.log(`
@@ -30,7 +37,7 @@ const help = () => {
'DIR'
)} Path to the global ${'`.vercel`'} directory
-d, --debug Debug mode [off]
--env [filename] The file to write Development Environment Variables to [.env]
--environment [environment] Deployment environment [development]
-y, --yes Skip the confirmation prompt
${chalk.dim('Examples:')}
@@ -41,32 +48,51 @@ const help = () => {
${chalk.cyan(`$ ${getPkgName()} pull ./path-to-project`)}
${chalk.cyan(`$ ${getPkgName()} pull --env .env.local`)}
${chalk.cyan(`$ ${getPkgName()} pull ./path-to-project --env .env.local`)}
${chalk.gray('')} Pull specific environment's Project Settings from the cloud
${chalk.cyan(
`$ ${getPkgName()} pull --environment=${getEnvTargetPlaceholder()}`
)}
`);
};
export default async function main(client: Client) {
let argv;
function processArgs(client: Client) {
return getArgs(client.argv.slice(2), {
'--yes': Boolean,
'--env': String, // deprecated
'--environment': String,
'--debug': Boolean,
'-d': '--debug',
'-y': '--yes',
});
}
function parseArgs(client: Client) {
try {
argv = getArgs(client.argv.slice(2), {
'--yes': Boolean,
'--env': String,
'--debug': Boolean,
'-d': '--debug',
'-y': '--yes',
});
const argv = processArgs(client);
if (argv['--help']) {
help();
return 2;
}
return argv;
} catch (err) {
handleError(err);
return 1;
}
}
if (argv['--help']) {
help();
return 2;
}
const cwd = argv._[1] || process.cwd();
const yes = argv['--yes'];
const env = argv['--env'] ?? '.env';
const settingsStamp = stamp();
type LinkResult = {
org: Org;
project: Project;
};
async function ensureLink(
client: Client,
cwd: string,
yes: boolean
): Promise<LinkResult | number> {
let link = await getLinkedProject(client, cwd);
if (link.status === 'not_linked') {
link = await setupAndLink(client, cwd, {
@@ -85,24 +111,70 @@ export default async function main(client: Client) {
return link.exitCode;
}
return { org: link.org, project: link.project };
}
async function pullAllEnvFiles(
environment: ProjectEnvTarget,
client: Client,
project: Project,
argv: ReturnType<typeof processArgs>,
cwd: string
): Promise<number> {
const environmentFile = `.env.${environment}.local`;
return envPull(
client,
project,
environment,
argv,
[join('.vercel', environmentFile)],
client.output,
cwd
);
}
function parseEnvironment(environment = 'development'): ProjectEnvTarget {
if (!isValidEnvTarget(environment)) {
throw new Error(
`environment "${environment}" not supported; must be one of ${getEnvTargetPlaceholder()}`
);
}
return environment;
}
export default async function main(client: Client) {
const argv = parseArgs(client);
if (typeof argv === 'number') {
return argv;
}
const cwd = argv._[1] || process.cwd();
const yes = Boolean(argv['--yes']);
const environment = parseEnvironment(argv['--environment'] || undefined);
const link = await ensureLink(client, cwd, yes);
if (typeof link === 'number') {
return link;
}
const { project, org } = link;
client.config.currentTeam = org.type === 'team' ? org.id : undefined;
const result = await pull(
const pullResultCode = await pullAllEnvFiles(
environment,
client,
project,
argv,
[join(cwd, env)],
client.output
cwd
);
if (result !== 0) {
// an error happened
return result;
if (pullResultCode !== 0) {
return pullResultCode;
}
await writeProjectSettings(cwd, project, org);
const settingsStamp = stamp();
client.output.print(
`${prependEmoji(
`Downloaded project settings to ${chalk.bold(

View File

@@ -12,7 +12,7 @@ try {
}
import { join } from 'path';
import { existsSync, lstatSync } from 'fs';
import { existsSync } from 'fs';
import sourceMap from '@zeit/source-map-support';
import { mkdirp } from 'fs-extra';
import chalk from 'chalk';
@@ -136,6 +136,11 @@ const main = async () => {
return 1;
}
const cwd = argv['--cwd'];
if (cwd) {
process.chdir(cwd);
}
// Print update information, if available
if (notifier.update && notifier.update.latest !== pkg.version && isTTY) {
const { latest } = notifier.update;
@@ -386,34 +391,11 @@ const main = async () => {
GLOBAL_COMMANDS.has(targetOrSubcommand) ||
commands.has(targetOrSubcommand);
if (targetPathExists && subcommandExists) {
const fileType = lstatSync(targetPath).isDirectory()
? 'subdirectory'
: 'file';
const plural = targetOrSubcommand + 's';
const singular = targetOrSubcommand.endsWith('s')
? targetOrSubcommand.slice(0, -1)
: '';
let alternative = '';
if (commands.has(plural)) {
alternative = plural;
} else if (commands.has(singular)) {
alternative = singular;
}
console.error(
error(
`The supplied argument ${param(targetOrSubcommand)} is ambiguous.` +
`\nIf you wish to deploy the ${fileType} ${param(
targetOrSubcommand
)}, first run "cd ${targetOrSubcommand}". ` +
(alternative
? `\nIf you wish to use the subcommand ${param(
targetOrSubcommand
)}, use ${param(alternative)} instead.`
: '')
)
if (targetPathExists && subcommandExists && !argv['--cwd']) {
output.warn(
`Did you mean to deploy the subdirectory "${targetOrSubcommand}"? ` +
`Use \`vc --cwd ${targetOrSubcommand}\` instead.`
);
return 1;
}
if (subcommandExists) {

View File

@@ -25,7 +25,9 @@ const ARG_COMMON = {
'--api': String,
'--target': String
'--target': String,
'--cwd': String,
};
export default () => ARG_COMMON;

View File

@@ -1,4 +1,8 @@
import { ProjectEnvType, ProjectEnvVariable } from '../../types';
import {
ProjectEnvType,
ProjectEnvVariable,
ProjectEnvTarget,
} from '../../types';
import { Env } from '@vercel/build-utils';
function getSystemEnvValue(
@@ -16,13 +20,14 @@ export default function exposeSystemEnvs(
projectEnvs: ProjectEnvVariable[],
systemEnvValues: string[],
autoExposeSystemEnvs: boolean | undefined,
vercelUrl?: string
vercelUrl?: string,
target?: ProjectEnvTarget
) {
const envs: Env = {};
if (autoExposeSystemEnvs) {
envs['VERCEL'] = '1';
envs['VERCEL_ENV'] = 'development';
envs['VERCEL_ENV'] = target || 'development';
for (const key of systemEnvValues) {
envs[key] = getSystemEnvValue(key, { vercelUrl });

View File

@@ -26,7 +26,7 @@ export default async function addEnvRecord(
target: targets,
gitBranch: gitBranch || undefined,
};
const url = `/v7/projects/${projectId}/env`;
const url = `/v8/projects/${projectId}/env`;
await client.fetch(url, {
method: 'POST',
body: JSON.stringify(body),

View File

@@ -32,7 +32,7 @@ export default async function getEnvRecords(
query.set('decrypt', decrypt.toString());
}
const url = `/v7/projects/${projectId}/env?${query}`;
const url = `/v8/projects/${projectId}/env?${query}`;
return client.fetch<{ envs: ProjectEnvVariable[] }>(url);
}

View File

@@ -10,7 +10,7 @@ export default async function removeEnvRecord(
): Promise<void> {
output.debug(`Removing Environment Variable ${env.key}`);
const urlProject = `/v7/projects/${projectId}/env/${env.id}`;
const urlProject = `/v8/projects/${projectId}/env/${env.id}`;
await client.fetch<ProjectEnvVariable>(urlProject, {
method: 'DELETE',

View File

@@ -11,10 +11,11 @@ import getEnvRecords from './env/get-env-records';
export default async function getDecryptedEnvRecords(
output: Output,
client: Client,
projectId: string
projectId: string,
target?: ProjectEnvTarget
): Promise<{ envs: ProjectEnvVariable[] }> {
const { envs } = await getEnvRecords(output, client, projectId, {
target: ProjectEnvTarget.Development,
target: target || ProjectEnvTarget.Development,
decrypt: true,
});

View File

@@ -19,19 +19,24 @@ export default async function inputProject(
// attempt to auto-detect a project to link
let detectedProject = null;
output.spinner('Searching for existing projects…', 1000);
try {
const [project, slugifiedProject] = await Promise.all([
getProjectByIdOrName(client, detectedProjectName, org.id),
slugifiedName !== detectedProjectName
? getProjectByIdOrName(client, slugifiedName, org.id)
: null,
]);
detectedProject = !(project instanceof ProjectNotFound)
? project
: !(slugifiedProject instanceof ProjectNotFound)
? slugifiedProject
: null;
} catch (error) {}
const [project, slugifiedProject] = await Promise.all([
getProjectByIdOrName(client, detectedProjectName, org.id),
slugifiedName !== detectedProjectName
? getProjectByIdOrName(client, slugifiedName, org.id)
: null,
]);
detectedProject = !(project instanceof ProjectNotFound)
? project
: !(slugifiedProject instanceof ProjectNotFound)
? slugifiedProject
: null;
if (detectedProject && !detectedProject.id) {
throw new Error(`Detected linked project does not have "id".`);
}
output.stopSpinner();
if (autoConfirm) {

View File

@@ -9,7 +9,7 @@ export default async function getProjectByNameOrId(
) {
try {
const project = await client.fetch<Project>(
`/projects/${encodeURIComponent(projectNameOrId)}`,
`/v8/projects/${encodeURIComponent(projectNameOrId)}`,
{ accountId }
);
return project;

View File

@@ -20,9 +20,15 @@ describe('pull', () => {
client.setArgv('pull', '--yes', cwd);
const exitCode = await pull(client);
expect(exitCode).toEqual(0);
const rawDevEnv = await fs.readFile(
path.join(cwd, '.vercel', '.env.development.local')
);
const devFileHasDevEnv = rawDevEnv.toString().includes('SPECIAL_FLAG');
expect(devFileHasDevEnv).toBeTruthy();
});
it('should handle custom --env flag', async () => {
it('should handle --environment=preview flag', async () => {
const cwd = setupFixture('vercel-pull-next');
useUser();
useTeams();
@@ -31,15 +37,42 @@ describe('pull', () => {
id: 'vercel-pull-next',
name: 'vercel-pull-next',
});
const expectedEnvFilename = '.env.vercel';
client.setArgv('pull', '--yes', `--env=${expectedEnvFilename}`, cwd);
client.setArgv('pull', '--yes', '--environment=preview', cwd);
const exitCode = await pull(client);
const actualEnv = await fs.pathExists(path.join(cwd, expectedEnvFilename));
const raw = await fs.readFile(path.join(cwd, expectedEnvFilename));
expect(exitCode).toEqual(0);
expect(actualEnv).toBeTruthy();
expect(raw.includes('# Created by Vercel CLI')).toBeTruthy();
const rawPreviewEnv = await fs.readFile(
path.join(cwd, '.vercel', '.env.preview.local')
);
const previewFileHasPreviewEnv = rawPreviewEnv
.toString()
.includes('REDIS_CONNECTION_STRING');
expect(previewFileHasPreviewEnv).toBeTruthy();
});
it('should handle --environment=production flag', async () => {
const cwd = setupFixture('vercel-pull-next');
useUser();
useTeams();
useProject({
...defaultProject,
id: 'vercel-pull-next',
name: 'vercel-pull-next',
});
client.setArgv('pull', '--yes', '--environment=production', cwd);
const exitCode = await pull(client);
expect(exitCode).toEqual(0);
const rawProdEnv = await fs.readFile(
path.join(cwd, '.vercel', '.env.production.local')
);
const previewFileHasPreviewEnv1 = rawProdEnv
.toString()
.includes('REDIS_CONNECTION_STRING');
expect(previewFileHasPreviewEnv1).toBeTruthy();
const previewFileHasPreviewEnv2 = rawProdEnv
.toString()
.includes('SQL_CONNECTION_STRING');
expect(previewFileHasPreviewEnv2).toBeTruthy();
});
});

View File

@@ -168,6 +168,17 @@ module.exports = async function prepare(session, binaryPath) {
'vercel.json': JSON.stringify({ version: 2 }),
'README.md': 'readme contents',
},
'deploy-default-with-sub-directory': {
'vercel.json': JSON.stringify({ version: 2 }),
'output/README.md':
'readme contents for deploy-default-with-sub-directory',
},
'deploy-default-with-conflicting-sub-directory': {
'list/vercel.json': JSON.stringify({ version: 2 }),
'list/list/README.md': 'nested nested readme contents',
'list/README.md':
'readme contents for deploy-default-with-conflicting-sub-directory',
},
'local-config-v2': {
[`main-${session}.html`]: '<h1>hello main</h1>',
[`test-${session}.html`]: '<h1>hello test</h1>',
@@ -192,10 +203,6 @@ module.exports = async function prepare(session, binaryPath) {
name: 'nested-level',
}),
},
'subdirectory-secret': {
'index.html': 'Home page',
'secret/file.txt': 'my secret',
},
'build-secret': {
'package.json': JSON.stringify({
private: true,

View File

@@ -125,6 +125,19 @@ ${stdout}
`;
}
async function vcLink(t, projectPath) {
const { exitCode, stderr, stdout } = await execa(
binaryPath,
['link', '--confirm', ...defaultArgs],
{
reject: false,
cwd: projectPath,
}
);
t.is(exitCode, 0, formatOutput({ stderr, stdout }));
}
// AVA's `t.context` can only be set before the tests,
// but we want to set it within as well
const context = {};
@@ -355,6 +368,8 @@ test('default command should prompt login with empty auth.json', async t => {
}
});
// NOTE: Test order is important here.
// This test MUST run before the tests below for them to work.
test('login', async t => {
t.timeout(ms('1m'));
@@ -378,6 +393,110 @@ test('login', async t => {
t.is(auth.token, token);
});
test('default command should deploy directory', async t => {
const projectDir = fixture('deploy-default-with-sub-directory');
const target = 'output';
await vcLink(t, path.join(projectDir, target));
const { exitCode, stderr, stdout } = await execa(
binaryPath,
[
// omit the default "deploy" command
target,
...defaultArgs,
],
{
cwd: projectDir,
}
);
t.is(exitCode, 0, formatOutput({ stdout, stderr }));
t.regex(stdout, /https:\/\/output-.+\.vercel\.app/);
});
test('default command should warn when deploying with conflicting subdirectory', async t => {
const projectDir = fixture('deploy-default-with-conflicting-sub-directory');
const target = 'list'; // command that conflicts with a sub directory
await vcLink(t, projectDir);
const { exitCode, stderr, stdout } = await execa(
binaryPath,
[
// omit the default "deploy" command
target,
...defaultArgs,
],
{
cwd: projectDir,
}
);
t.is(exitCode, 0, formatOutput({ stdout, stderr }));
t.regex(
stderr || '',
/Did you mean to deploy the subdirectory "list"\? Use `vc --cwd list` instead./
);
const listHeader = /project +latest deployment +state +age +username/;
t.regex(stdout || '', listHeader); // ensure `list` command still ran
});
test('deploy command should not warn when deploying with conflicting subdirectory and using --cwd', async t => {
const projectDir = fixture('deploy-default-with-conflicting-sub-directory');
const target = 'list'; // command that conflicts with a sub directory
await vcLink(t, path.join(projectDir, target));
const { exitCode, stderr, stdout } = await execa(
binaryPath,
['list', '--cwd', target, ...defaultArgs],
{
cwd: projectDir,
}
);
t.is(exitCode, 0, formatOutput({ stdout, stderr }));
t.notRegex(
stderr || '',
/Did you mean to deploy the subdirectory "list"\? Use `vc --cwd list` instead./
);
const listHeader = /project +latest deployment +state +age +username/;
t.regex(stdout || '', listHeader); // ensure `list` command still ran
});
test('default command should work with --cwd option', async t => {
const projectDir = fixture('deploy-default-with-conflicting-sub-directory');
const target = 'list'; // command that conflicts with a sub directory
await vcLink(t, path.join(projectDir, 'list'));
const { exitCode, stderr, stdout } = await execa(
binaryPath,
[
// omit the default "deploy" command
'--cwd',
target,
...defaultArgs,
],
{
cwd: projectDir,
}
);
t.is(exitCode, 0, formatOutput({ stderr, stdout }));
const url = stdout;
const deploymentResult = await fetch(`${url}/README.md`);
const body = await deploymentResult.text();
t.deepEqual(
body,
'readme contents for deploy-default-with-conflicting-sub-directory'
);
});
test('deploy using only now.json with `redirects` defined', async t => {
const target = fixture('redirects-v2');
@@ -1088,30 +1207,6 @@ test('output the version', async t => {
t.is(version, pkg.version);
});
test('should error with suggestion for secrets subcommand', async t => {
const target = fixture('subdirectory-secret');
const { exitCode, stderr, stdout } = await execa(
binaryPath,
['secret', 'add', 'key', 'value', ...defaultArgs],
{
cwd: target,
reject: false,
}
);
console.log(stderr);
console.log(stdout);
console.log(exitCode);
t.is(exitCode, 1);
t.regex(
stderr,
/secrets/gm,
`Expected "secrets" suggestion but received "${stderr}"`
);
});
test('should add secret with hyphen prefix', async t => {
const target = fixture('build-secret');
const key = 'mysecret';

View File

@@ -23,6 +23,17 @@ const envs = [
updatedAt: 1557241361445,
createdAt: 1557241361445,
},
{
type: 'encrypted',
id: 'a235l6frtu25df32',
key: 'SPECIAL_FLAG',
value: '1',
target: ['development'],
gitBranch: null,
configurationId: null,
updatedAt: 1557241361445,
createdAt: 1557241361445,
},
];
export const defaultProject = {
@@ -77,13 +88,19 @@ export const defaultProject = {
};
export function useProject(project = defaultProject) {
client.scenario.get(`/projects/${project.name}`, (_req, res) => {
client.scenario.get(`/v8/projects/${project.name}`, (_req, res) => {
res.json(project);
});
client.scenario.get(`/projects/${project.id}`, (_req, res) => {
client.scenario.get(`/v8/projects/${project.id}`, (_req, res) => {
res.json(project);
});
client.scenario.get(`/v7/projects/${project.id}/env`, (_req, res) => {
client.scenario.get(`/v8/projects/${project.id}/env`, (_req, res) => {
const target = _req.query.target;
if (typeof target === 'string') {
const targetEnvs = envs.filter(env => env.target.includes(target));
res.json({ envs: targetEnvs });
}
res.json({ envs });
});

View File

@@ -11,7 +11,10 @@ import DevServer from '../../../src/util/dev/server';
async function runNpmInstall(fixturePath: string) {
if (await fs.pathExists(path.join(fixturePath, 'package.json'))) {
return execa('yarn', ['install'], { cwd: fixturePath, shell: true });
return execa('yarn', ['install', '--network-timeout', '1000000'], {
cwd: fixturePath,
shell: true,
});
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/client",
"version": "10.4.1-canary.0",
"version": "10.4.1",
"main": "dist/index.js",
"typings": "dist/index.d.ts",
"homepage": "https://vercel.com",
@@ -41,7 +41,7 @@
]
},
"dependencies": {
"@vercel/build-utils": "2.15.1-canary.0",
"@vercel/build-utils": "2.15.1",
"@zeit/fetch": "5.2.0",
"async-retry": "1.2.3",
"async-sema": "3.0.0",

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/frameworks",
"version": "0.7.1-canary.0",
"version": "0.7.1",
"main": "./dist/frameworks.js",
"types": "./dist/frameworks.d.ts",
"files": [
@@ -20,7 +20,7 @@
"@types/js-yaml": "3.12.1",
"@types/node": "12.0.4",
"@types/node-fetch": "2.5.8",
"@vercel/routing-utils": "1.13.1-canary.0",
"@vercel/routing-utils": "1.13.1",
"ajv": "6.12.2",
"typescript": "4.3.4"
}

View File

@@ -61,13 +61,13 @@ export interface Framework {
*/
logo: string;
/**
* A URL to the logo of a screenshot of the framework
* @example "https://assets.vercel.com/image/upload/v1647366075/front/import/nuxtjs.png"
* A URL to a screenshot of the demo
* @example "https://assets.vercel.com/image/upload/v1647366075/front/import/nextjs.png"
*/
screenshot?: string;
/**
* A URL to a deployed example of the framework
* @example "https://nextjs.now-examples.vercel.app"
* @example "https://nextjs-template.vercel.app"
*/
demo?: string;
/**

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/go",
"version": "1.3.2-canary.0",
"version": "1.3.2",
"license": "MIT",
"main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/go",
@@ -24,7 +24,7 @@
"@types/fs-extra": "^5.0.5",
"@types/node-fetch": "^2.3.0",
"@types/tar": "^4.0.0",
"@vercel/build-utils": "2.15.1-canary.0",
"@vercel/build-utils": "2.15.1",
"@vercel/ncc": "0.24.0",
"async-retry": "1.3.1",
"execa": "^1.0.0",

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/node",
"version": "1.14.1-canary.0",
"version": "1.14.1",
"license": "MIT",
"main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/node-js",
@@ -32,7 +32,7 @@
"@types/cookie": "0.3.3",
"@types/etag": "1.8.0",
"@types/test-listen": "1.1.0",
"@vercel/build-utils": "2.15.1-canary.0",
"@vercel/build-utils": "2.15.1",
"@vercel/ncc": "0.24.0",
"@vercel/nft": "0.17.5",
"content-type": "1.0.4",

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/python",
"version": "2.2.2-canary.0",
"version": "2.2.2",
"main": "./dist/index.js",
"license": "MIT",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/python",
@@ -20,7 +20,7 @@
},
"devDependencies": {
"@types/execa": "^0.9.0",
"@vercel/build-utils": "2.15.1-canary.0",
"@vercel/build-utils": "2.15.1",
"@vercel/ncc": "0.24.0",
"execa": "^1.0.0",
"typescript": "4.3.4"

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/redwood",
"version": "0.6.1-canary.0",
"version": "0.7.0",
"main": "./dist/index.js",
"license": "MIT",
"homepage": "https://vercel.com/docs",
@@ -19,13 +19,13 @@
},
"dependencies": {
"@vercel/nft": "0.17.5",
"@vercel/routing-utils": "1.13.1-canary.0",
"@vercel/routing-utils": "1.13.1",
"semver": "6.1.1"
},
"devDependencies": {
"@types/aws-lambda": "8.10.19",
"@types/node": "*",
"@types/semver": "6.0.0",
"@vercel/build-utils": "2.15.1-canary.0"
"@vercel/build-utils": "2.15.1"
}
}

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/routing-utils",
"version": "1.13.1-canary.0",
"version": "1.13.1",
"description": "Vercel routing utilities",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",

View File

@@ -1,7 +1,7 @@
{
"name": "@vercel/ruby",
"author": "Nathan Cahill <nathan@nathancahill.com>",
"version": "1.3.2-canary.0",
"version": "1.3.2",
"license": "MIT",
"main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/ruby",
@@ -22,7 +22,7 @@
"devDependencies": {
"@types/fs-extra": "8.0.0",
"@types/semver": "6.0.0",
"@vercel/build-utils": "2.15.1-canary.0",
"@vercel/build-utils": "2.15.1",
"@vercel/ncc": "0.24.0",
"execa": "2.0.4",
"fs-extra": "^7.0.1",

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/static-build",
"version": "0.23.1-canary.0",
"version": "0.23.1",
"license": "MIT",
"main": "./dist/index",
"homepage": "https://vercel.com/docs/build-step",
@@ -24,10 +24,10 @@
"@types/ms": "0.7.31",
"@types/node-fetch": "2.5.4",
"@types/promise-timeout": "1.3.0",
"@vercel/build-utils": "2.15.1-canary.0",
"@vercel/frameworks": "0.7.1-canary.0",
"@vercel/build-utils": "2.15.1",
"@vercel/frameworks": "0.7.1",
"@vercel/ncc": "0.24.0",
"@vercel/routing-utils": "1.13.1-canary.0",
"@vercel/routing-utils": "1.13.1",
"get-port": "5.0.0",
"is-port-reachable": "2.0.1",
"ms": "2.1.2",

View File

@@ -10,7 +10,6 @@ import { cpus } from 'os';
import {
BuildV2,
Files,
FileFsRef,
Config,
PackageJson,
PrepareCache,
@@ -211,9 +210,15 @@ function getPkg(entrypoint: string, workPath: string) {
return null;
}
const pkgPath = path.join(workPath, entrypoint);
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8')) as PackageJson;
return pkg;
try {
const pkgPath = path.join(workPath, entrypoint);
const pkg = JSON.parse(readFileSync(pkgPath, 'utf8')) as PackageJson;
return pkg;
} catch (err: any) {
if (err.code !== 'ENOENT') throw err;
}
return null;
}
function getFramework(
@@ -742,31 +747,32 @@ export const prepareCache: PrepareCache = async ({
workPath,
config,
}) => {
const cacheFiles: Files = {};
// File System API v1 cache files
const buildConfig = await readBuildOutputConfig<BuildConfig>({
workPath,
configFileName: 'build.json',
});
if (buildConfig?.cache && Array.isArray(buildConfig.cache)) {
const cacheFiles = {};
for (const cacheGlob of buildConfig.cache) {
Object.assign(cacheFiles, await glob(cacheGlob, workPath));
}
return cacheFiles;
}
const defaultCacheFiles = await glob(
'{.shadow-cljs,node_modules}/**',
workPath
// Default cache files
Object.assign(
cacheFiles,
await glob('{.shadow-cljs,node_modules}/**', workPath)
);
let frameworkCacheFiles: { [path: string]: FileFsRef } = {};
// Framework cache files
const pkg = getPkg(entrypoint, workPath);
const framework = getFramework(config, pkg);
if (framework?.cachePattern) {
frameworkCacheFiles = await glob(framework.cachePattern, workPath);
Object.assign(cacheFiles, await glob(framework.cachePattern, workPath));
}
return { ...defaultCacheFiles, ...frameworkCacheFiles };
return cacheFiles;
};

View File

@@ -1 +1 @@
pelican==4.1.1
pelican==4.7.2

View File

@@ -1 +1 @@
mkdocs==1.0.4
mkdocs==1.2.4