Compare commits

..

9 Commits

Author SHA1 Message Date
Nathan Rajlich
46348201b4 Publish Stable
- @vercel/build-utils@6.7.0
 - vercel@28.18.3
 - @vercel/client@12.4.8
 - @vercel/fs-detectors@3.8.8
 - @vercel/gatsby-plugin-vercel-builder@1.2.6
 - @vercel/go@2.4.3
 - @vercel/hydrogen@0.0.61
 - @vercel/next@3.7.3
 - @vercel/node@2.10.2
 - @vercel/python@3.1.57
 - @vercel/redwood@1.1.13
 - @vercel/remix-builder@1.8.3
 - @vercel/ruby@1.3.74
 - @vercel/static-build@1.3.21
2023-03-29 12:25:26 -07:00
Nathan Rajlich
509926545e [build-utils] Rename Lambda experimentalResponseStreaming prop to supportsResponseStreaming (#9721) 2023-03-29 12:11:09 -07:00
Sean Massa
70c8b32cf0 [tests] Split CLI integration tests into chunks (#9688)
Welcome to the grand splitting of CLI integration tests:

- replaced `test-cli` test suite with `test-e2e`
- made some small fixes along the way
- split integration tests into 3 files
- moved shared logic to `packages/cli/test/helpers/*`
- simplified `_execa` / `execa` / `execute` usage into `execCli` and `exec`
    - simplified arguments required to make these work
- defaulted `execCLI` to set `NO_COLOR=1` to make assertions simpler in tests that aren't testing color/emoji support
- expanded functionality of `formatOutput` to handle error states
- centralized temp dir handling and cleanup
- enhanced `waitForPrompt` to:
    - more clearly show what it was waiting for
    - support waiting for regex, string, or a function that returns a boolean
    - show what was the most recent thing it saw
    - end early if the process it's monitoring exits
- removed some test pollution where unnecessary, shifted some into `beforeAll`
- renamed unit tests helper from `setupFixture` to `setupUnitFixture` to avoid confusion with the new shared helper `setupE2EFixture`


Some of this could be pulled out into a separate PR, but the feedback cycle is a slog, which this PR is helping to address. I'd be happy to discuss what could be pulled out, but I'd also be happy to get the whole thing through.

---

Wait for prompt failures:

<img width="939" alt="CleanShot 2023-03-27 at 10 24 21@2x" src="https://user-images.githubusercontent.com/41545/227987773-a3582549-32f9-4131-8a35-7be7cc265b66.png">

---

Current Timing:

```
Tests / test-e2e (vercel, 1, ubuntu-latest) (pull_request) Successful in 3m
Tests / test-e2e (vercel, 2, ubuntu-latest) (pull_request) Successful in 8m
Tests / test-e2e (vercel, 3, ubuntu-latest) (pull_request) Successful in 8m
```

---

Before merge, I'll mark the original `CLI` integration test suite as no longer required.
2023-03-29 07:44:42 +00:00
Sean Massa
54514a44af Publish Stable
- @vercel/build-utils@6.6.0
 - vercel@28.18.2
 - @vercel/client@12.4.7
 - @vercel/fs-detectors@3.8.7
 - @vercel/gatsby-plugin-vercel-builder@1.2.5
 - @vercel/go@2.4.2
 - @vercel/hydrogen@0.0.60
 - @vercel/next@3.7.2
 - @vercel/node-bridge@4.0.0
 - @vercel/node@2.10.1
 - @vercel/python@3.1.56
 - @vercel/redwood@1.1.12
 - @vercel/remix-builder@1.8.2
 - @vercel/ruby@1.3.73
 - @vercel/static-build@1.3.20
2023-03-27 22:25:08 -05:00
Ethan Arrowood
0db8fadf74 [build-utils] add pnpm v8 auto detection (#9720)
Adds automatic detection for pnpm v8 based on lockfile v6
2023-03-27 23:07:39 +00:00
Sean Massa
6f01e5ab75 [cli] support build -y shorthand (#9717)
The `build` command wasn't supporting the `-y` shorthand for `--yes`. Now it does.

I looked at the other uses and they all seem fine.
2023-03-27 15:18:16 +00:00
Kiko Beats
78d45f9e7e [node-bridge] add feature flags support (#9713)
This PR allows executing conditional logic based in feature flags.

---------

Co-authored-by: Steven <steven@ceriously.com>
2023-03-26 10:34:12 +02:00
Kiko Beats
22e1a6a9ce [node-bridge]: remove API Gateway normalization (#9711)
We no longer use since a long time ago
2023-03-24 20:12:36 +01:00
Steven
8391734b5e [build-utils] Fix system env var detection for prefixed env vars (#9709)
This PR fixes a bug that was causing too many env vars to be exposed to the frontend by adding the framework `envPrefix`.

Some frameworks, such as CRA, will include all of these in the frontend even if not explicitly used so we must only prefix known [System Environment Variables](https://vercel.com/docs/concepts/projects/environment-variables/system-environment-variables).

This PR adds an allowlist to ensure this is handle properly.

- Fixes https://linear.app/vercel/issue/VCCLI-639
2023-03-24 05:45:27 +00:00
57 changed files with 4309 additions and 4073 deletions

View File

@@ -1,44 +0,0 @@
name: CLI
on:
push:
branches:
- main
tags:
- '!*'
pull_request:
env:
TURBO_REMOTE_ONLY: 'true'
TURBO_TEAM: 'vercel'
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
jobs:
test:
name: CLI
timeout-minutes: 40
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
node: [16]
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 2
- uses: actions/setup-node@v3
with:
node-version: ${{ matrix.node }}
- name: install pnpm@7.24.2
run: npm i -g pnpm@7.24.2
- run: pnpm install
- run: pnpm run build
- run: pnpm test-cli
env:
VERCEL_TEST_TOKEN: ${{ secrets.VERCEL_TEST_TOKEN }}
VERCEL_TEST_REGISTRATION_URL: ${{ secrets.VERCEL_TEST_REGISTRATION_URL }}

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/build-utils", "name": "@vercel/build-utils",
"version": "6.5.0", "version": "6.7.0",
"license": "MIT", "license": "MIT",
"main": "./dist/index.js", "main": "./dist/index.js",
"types": "./dist/index.d.js", "types": "./dist/index.d.js",

View File

@@ -487,6 +487,7 @@ export function getEnvForPackageManager({
const oldPath = env.PATH + ''; const oldPath = env.PATH + '';
const npm7 = '/node16/bin-npm7'; const npm7 = '/node16/bin-npm7';
const pnpm7 = '/pnpm7/node_modules/.bin'; const pnpm7 = '/pnpm7/node_modules/.bin';
const pnpm8 = '/pnpm8/node_modules/.bin';
const corepackEnabled = env.ENABLE_EXPERIMENTAL_COREPACK === '1'; const corepackEnabled = env.ENABLE_EXPERIMENTAL_COREPACK === '1';
if (cliType === 'npm') { if (cliType === 'npm') {
if ( if (
@@ -509,7 +510,20 @@ export function getEnvForPackageManager({
) { ) {
// Ensure that pnpm 7 is at the beginning of the `$PATH` // Ensure that pnpm 7 is at the beginning of the `$PATH`
newEnv.PATH = `${pnpm7}${path.delimiter}${oldPath}`; newEnv.PATH = `${pnpm7}${path.delimiter}${oldPath}`;
console.log('Detected `pnpm-lock.yaml` generated by pnpm 7...'); console.log(
`Detected \`pnpm-lock.yaml\` version ${lockfileVersion} generated by pnpm 7...`
);
} else if (
typeof lockfileVersion === 'number' &&
lockfileVersion >= 6 &&
!oldPath.includes(pnpm8) &&
!corepackEnabled
) {
// Ensure that pnpm 8 is at the beginning of the `$PATH`
newEnv.PATH = `${pnpm8}${path.delimiter}${oldPath}`;
console.log(
`Detected \`pnpm-lock.yaml\` version ${lockfileVersion} generated by pnpm 8...`
);
} }
} else { } else {
// Yarn v2 PnP mode may be activated, so force "node-modules" linker style // Yarn v2 PnP mode may be activated, so force "node-modules" linker style

View File

@@ -14,10 +14,11 @@ export function getPrefixedEnvVars({
envs: Envs; envs: Envs;
}): Envs { }): Envs {
const vercelSystemEnvPrefix = 'VERCEL_'; const vercelSystemEnvPrefix = 'VERCEL_';
const allowed = ['VERCEL_URL', 'VERCEL_ENV', 'VERCEL_REGION'];
const newEnvs: Envs = {}; const newEnvs: Envs = {};
if (envPrefix && envs.VERCEL_URL) { if (envPrefix && envs.VERCEL_URL) {
Object.keys(envs) Object.keys(envs)
.filter(key => key.startsWith(vercelSystemEnvPrefix)) .filter(key => allowed.includes(key) || key.startsWith('VERCEL_GIT_'))
.forEach(key => { .forEach(key => {
const newKey = `${envPrefix}${key}`; const newKey = `${envPrefix}${key}`;
if (!(newKey in envs)) { if (!(newKey in envs)) {

View File

@@ -23,6 +23,10 @@ export interface LambdaOptionsBase {
regions?: string[]; regions?: string[];
supportsMultiPayloads?: boolean; supportsMultiPayloads?: boolean;
supportsWrapper?: boolean; supportsWrapper?: boolean;
supportsResponseStreaming?: boolean;
/**
* @deprecated Use the `supportsResponseStreaming` property instead.
*/
experimentalResponseStreaming?: boolean; experimentalResponseStreaming?: boolean;
operationType?: string; operationType?: string;
framework?: FunctionFramework; framework?: FunctionFramework;
@@ -69,7 +73,7 @@ export class Lambda {
zipBuffer?: Buffer; zipBuffer?: Buffer;
supportsMultiPayloads?: boolean; supportsMultiPayloads?: boolean;
supportsWrapper?: boolean; supportsWrapper?: boolean;
experimentalResponseStreaming?: boolean; supportsResponseStreaming?: boolean;
framework?: FunctionFramework; framework?: FunctionFramework;
constructor(opts: LambdaOptions) { constructor(opts: LambdaOptions) {
@@ -83,6 +87,7 @@ export class Lambda {
regions, regions,
supportsMultiPayloads, supportsMultiPayloads,
supportsWrapper, supportsWrapper,
supportsResponseStreaming,
experimentalResponseStreaming, experimentalResponseStreaming,
operationType, operationType,
framework, framework,
@@ -162,7 +167,8 @@ export class Lambda {
this.zipBuffer = 'zipBuffer' in opts ? opts.zipBuffer : undefined; this.zipBuffer = 'zipBuffer' in opts ? opts.zipBuffer : undefined;
this.supportsMultiPayloads = supportsMultiPayloads; this.supportsMultiPayloads = supportsMultiPayloads;
this.supportsWrapper = supportsWrapper; this.supportsWrapper = supportsWrapper;
this.experimentalResponseStreaming = experimentalResponseStreaming; this.supportsResponseStreaming =
supportsResponseStreaming ?? experimentalResponseStreaming;
this.framework = framework; this.framework = framework;
} }
@@ -181,6 +187,16 @@ export class Lambda {
} }
return zipBuffer; return zipBuffer;
} }
/**
* @deprecated Use the `supportsResponseStreaming` property instead.
*/
get experimentalResponseStreaming(): boolean | undefined {
return this.supportsResponseStreaming;
}
set experimentalResponseStreaming(v: boolean | undefined) {
this.supportsResponseStreaming = v;
}
} }
const sema = new Sema(10); const sema = new Sema(10);

View File

@@ -4,8 +4,7 @@
"probes": [ "probes": [
{ {
"path": "/", "path": "/",
"mustContain": "pnpm version: 6", "mustContain": "pnpm version: 7"
"logMustContain": "pnpm run build"
} }
] ]
} }

View File

@@ -0,0 +1,9 @@
{
"private": true,
"scripts": {
"build": "mkdir -p public && (printf \"pnpm version: \" && pnpm -v) > public/index.txt"
},
"dependencies": {
"once": "^1.4.0"
}
}

View File

@@ -0,0 +1,21 @@
lockfileVersion: 5.4
importers:
.:
specifiers:
once: ^1.4.0
dependencies:
once: 1.4.0
packages:
/once/1.4.0:
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
dependencies:
wrappy: 1.0.2
dev: false
/wrappy/1.0.2:
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
dev: false

View File

@@ -0,0 +1 @@
# Empty so this is treated as its own pnpm workspace

View File

@@ -0,0 +1,8 @@
{
"probes": [
{
"path": "/",
"mustContain": "pnpm version: 7"
}
]
}

View File

@@ -0,0 +1,9 @@
{
"private": true,
"scripts": {
"build": "mkdir -p public && (printf \"pnpm version: \" && pnpm -v) > public/index.txt"
},
"dependencies": {
"once": "^1.4.0"
}
}

View File

@@ -0,0 +1,21 @@
lockfileVersion: '6.0'
importers:
.:
dependencies:
once:
specifier: ^1.4.0
version: 1.4.0
packages:
/once@1.4.0:
resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
dependencies:
wrappy: 1.0.2
dev: false
/wrappy@1.0.2:
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
dev: false

View File

@@ -0,0 +1 @@
# Empty so this is treated as its own pnpm workspace

View File

@@ -0,0 +1,8 @@
{
"probes": [
{
"path": "/",
"mustContain": "pnpm version: 8"
}
]
}

View File

@@ -14,6 +14,7 @@ describe('Test `getPrefixedEnvVars()`', () => {
VERCEL: '1', VERCEL: '1',
VERCEL_URL: 'example.vercel.sh', VERCEL_URL: 'example.vercel.sh',
USER_ENV_VAR_NOT_VERCEL: 'example.com', USER_ENV_VAR_NOT_VERCEL: 'example.com',
VERCEL_ARTIFACTS_TOKEN: 'abc123',
FOO: 'bar', FOO: 'bar',
}, },
}, },
@@ -28,6 +29,7 @@ describe('Test `getPrefixedEnvVars()`', () => {
envPrefix: 'GATSBY_', envPrefix: 'GATSBY_',
envs: { envs: {
USER_ENV_VAR_NOT_VERCEL: 'example.com', USER_ENV_VAR_NOT_VERCEL: 'example.com',
VERCEL_ARTIFACTS_TOKEN: 'abc123',
FOO: 'bar', FOO: 'bar',
VERCEL_URL: 'example.vercel.sh', VERCEL_URL: 'example.vercel.sh',
VERCEL_ENV: 'production', VERCEL_ENV: 'production',
@@ -51,6 +53,7 @@ describe('Test `getPrefixedEnvVars()`', () => {
USER_ENV_VAR_NOT_VERCEL: 'example.com', USER_ENV_VAR_NOT_VERCEL: 'example.com',
FOO: 'bar', FOO: 'bar',
BLARG_VERCEL_THING: 'fake', BLARG_VERCEL_THING: 'fake',
VERCEL_ARTIFACTS_TOKEN: 'abc123',
}, },
}, },
want: {}, want: {},

View File

@@ -1,6 +1,6 @@
{ {
"name": "vercel", "name": "vercel",
"version": "28.18.1", "version": "28.18.3",
"preferGlobal": true, "preferGlobal": true,
"license": "Apache-2.0", "license": "Apache-2.0",
"description": "The command-line interface for Vercel", "description": "The command-line interface for Vercel",
@@ -14,7 +14,7 @@
"preinstall": "node ./scripts/preinstall.js", "preinstall": "node ./scripts/preinstall.js",
"test": "jest --env node --verbose --bail", "test": "jest --env node --verbose --bail",
"test-unit": "pnpm test test/unit/", "test-unit": "pnpm test test/unit/",
"test-cli": "rimraf test/fixtures/integration && pnpm test test/integration.test.ts", "test-e2e": "rimraf test/fixtures/integration && pnpm test test/integration-1.test.ts test/integration-2.test.ts test/integration-3.test.ts",
"test-dev": "pnpm test test/dev/", "test-dev": "pnpm test test/dev/",
"coverage": "codecov", "coverage": "codecov",
"build": "ts-node ./scripts/build.ts", "build": "ts-node ./scripts/build.ts",
@@ -32,16 +32,16 @@
"node": ">= 14" "node": ">= 14"
}, },
"dependencies": { "dependencies": {
"@vercel/build-utils": "6.5.0", "@vercel/build-utils": "6.7.0",
"@vercel/go": "2.4.1", "@vercel/go": "2.4.3",
"@vercel/hydrogen": "0.0.59", "@vercel/hydrogen": "0.0.61",
"@vercel/next": "3.7.1", "@vercel/next": "3.7.3",
"@vercel/node": "2.10.0", "@vercel/node": "2.10.2",
"@vercel/python": "3.1.55", "@vercel/python": "3.1.57",
"@vercel/redwood": "1.1.11", "@vercel/redwood": "1.1.13",
"@vercel/remix-builder": "1.8.1", "@vercel/remix-builder": "1.8.3",
"@vercel/ruby": "1.3.72", "@vercel/ruby": "1.3.74",
"@vercel/static-build": "1.3.19" "@vercel/static-build": "1.3.21"
}, },
"devDependencies": { "devDependencies": {
"@alex_neo/jest-expect-message": "1.0.5", "@alex_neo/jest-expect-message": "1.0.5",
@@ -85,10 +85,10 @@
"@types/write-json-file": "2.2.1", "@types/write-json-file": "2.2.1",
"@types/yauzl-promise": "2.1.0", "@types/yauzl-promise": "2.1.0",
"@vercel-internals/types": "*", "@vercel-internals/types": "*",
"@vercel/client": "12.4.6", "@vercel/client": "12.4.8",
"@vercel/error-utils": "1.0.8", "@vercel/error-utils": "1.0.8",
"@vercel/frameworks": "1.3.3", "@vercel/frameworks": "1.3.3",
"@vercel/fs-detectors": "3.8.6", "@vercel/fs-detectors": "3.8.8",
"@vercel/fun": "1.0.4", "@vercel/fun": "1.0.4",
"@vercel/ncc": "0.24.0", "@vercel/ncc": "0.24.0",
"@vercel/routing-utils": "2.1.11", "@vercel/routing-utils": "2.1.11",

View File

@@ -157,6 +157,7 @@ export default async function main(client: Client): Promise<number> {
'--output': String, '--output': String,
'--prod': Boolean, '--prod': Boolean,
'--yes': Boolean, '--yes': Boolean,
'-y': '--yes',
}); });
if (argv['--help']) { if (argv['--help']) {

View File

@@ -99,7 +99,7 @@ const main = async client => {
if (argv.help || !subcommand) { if (argv.help || !subcommand) {
help(); help();
await exit(0); await exit(2);
} }
const { const {

View File

@@ -0,0 +1,57 @@
import execa from 'execa';
import getGlobalDir from './get-global-dir';
const defaultOptions = {
reject: false,
};
let globalArgs: string[] = [];
function getGlobalArgs() {
if (process.env.CI) {
return [];
}
if (globalArgs.length === 0) {
globalArgs = ['-Q', getGlobalDir()];
console.log(
'No CI detected, adding defaultArgs to avoid polluting user settings',
globalArgs
);
}
return globalArgs;
}
/**
* Execute Vercel CLI subcommands.
*/
export function execCli(
file: string,
args: string[] = [],
options?: execa.Options<string>
): execa.ExecaChildProcess<string> {
console.log(`$ vercel ${args.join(' ')}`);
const globalArgs = getGlobalArgs();
const combinedOptions: execa.Options<string> = {
...defaultOptions,
...options,
};
// @ts-ignore - allow overwriting readonly property "env"
combinedOptions.env = combinedOptions.env ?? {};
combinedOptions.env['NO_COLOR'] = combinedOptions.env['NO_COLOR'] ?? '1';
return execa(file, [...args, ...globalArgs], combinedOptions);
}
/**
* Execute an abitrary command.
*/
export function exec(cwd: string, command: string, args: string[] = []) {
return execa(command, args, {
cwd,
...defaultOptions,
});
}

View File

@@ -0,0 +1,44 @@
type ProcOrError = Partial<Error> & {
stdout: string;
stderr: string;
};
function indent(content: string) {
return ' ' + content.replace(/\n/g, '\n ');
}
function getMessages(output: ProcOrError) {
const { stdout, stderr, message } = output;
const messages = [];
if (stdout) {
messages.push(`Stdout:\n${indent(stdout)}`);
}
if (stderr) {
messages.push(`Stderr:\n${indent(stderr)}`);
}
// only show the spawn error if no better details are available
if (messages.length === 0 && message) {
messages.push(`Spawn Error:\n${indent(message)}`);
}
return messages;
}
function combineMessages(messages: string[], output: ProcOrError) {
if (messages.length === 0) {
return output.toString();
}
return messages.join(`\n\n-----\n\n`);
}
export default function formatOutput(output: ProcOrError) {
const messages = getMessages(output);
const combinedMessage = combineMessages(messages, output);
const borderedMessage = `-----\n\n${combinedMessage}\n\n-----`;
// add 2-space indent to match the Custom Message indent
return indent(borderedMessage).trim();
}

View File

@@ -0,0 +1,21 @@
import path from 'path';
import fs, { ensureDirSync } from 'fs-extra';
import XDGAppPaths from 'xdg-app-paths';
import { getCachedTmpDir } from './get-tmp-dir';
export default function getGlobalDir() {
let globalDir: string;
if (process.env.CI) {
globalDir = XDGAppPaths('com.vercel.cli').dataDirs()[0];
} else {
globalDir = path.join(getCachedTmpDir(), 'com.vercel.tests');
}
if (!fs.existsSync(globalDir)) {
console.log('Creating global config directory ', globalDir);
ensureDirSync(globalDir);
}
return globalDir;
}

View File

@@ -0,0 +1,36 @@
// @ts-ignore
import tmp from 'tmp-promise';
import type { TmpDir } from './types';
const allTmpDirs: TmpDir[] = [];
let cachedTmpDir: TmpDir | undefined;
export function getCachedTmpDir(): string {
if (cachedTmpDir) {
return cachedTmpDir.name;
}
cachedTmpDir = tmp.dirSync({
// This ensures the directory gets
// deleted even if it has contents
unsafeCleanup: true,
}) as TmpDir;
allTmpDirs.push(cachedTmpDir);
return cachedTmpDir.name;
}
export function getNewTmpDir(): string {
const tmpDir = tmp.dirSync({
// This ensures the directory gets
// deleted even if it has contents
unsafeCleanup: true,
}) as TmpDir;
allTmpDirs.push(tmpDir);
return tmpDir.name;
}
export function listTmpDirs() {
return allTmpDirs;
}

View File

@@ -0,0 +1,27 @@
import path from 'path';
import fs from 'fs-extra';
import prepareFixtures from './prepare';
import getGlobalDir from './get-global-dir';
function getTmpFixturesDir() {
return path.join(getGlobalDir(), 'tmp-fixtures');
}
export async function setupE2EFixture(name: string) {
const directory = path.join(getTmpFixturesDir(), name);
const config = path.join(directory, 'project.json');
// We need to remove it, otherwise we can't re-use fixtures
if (fs.existsSync(config)) {
fs.unlinkSync(config);
}
return directory;
}
export async function prepareE2EFixtures(
contextName: string,
binaryPath: string
) {
await prepareFixtures(contextName, binaryPath, getTmpFixturesDir());
}

View File

@@ -1,6 +1,7 @@
import findUp from 'find-up'; import findUp from 'find-up';
import fs from 'fs-extra'; import fs from 'fs-extra';
import path from 'path'; import path from 'path';
// @ts-ignore
import tmp from 'tmp-promise'; import tmp from 'tmp-promise';
// tmp is supposed to be able to clean up automatically, but this doesn't always work within jest. // tmp is supposed to be able to clean up automatically, but this doesn't always work within jest.
@@ -15,7 +16,7 @@ let tempNumber = 0;
* Create a temp directory containing the given fixture name in a git repo. * Create a temp directory containing the given fixture name in a git repo.
* Be sure to call `cleanupFixtures()` after all tests to clean up temp directories. * Be sure to call `cleanupFixtures()` after all tests to clean up temp directories.
*/ */
export function setupFixture(fixtureName: string) { export function setupUnitFixture(fixtureName: string) {
if (!fixturesRoot) { if (!fixturesRoot) {
fixturesRoot = findUp.sync('fixtures', { fixturesRoot = findUp.sync('fixtures', {
cwd: __dirname, cwd: __dirname,

View File

@@ -0,0 +1,21 @@
import type execa from 'execa';
export interface TmpDir {
name: string;
removeCallback: () => void;
}
export interface Build {
use: string;
}
export type NowJson = {
name: string;
};
export type DeploymentLike = {
error?: Error;
builds: Build[];
};
export type CLIProcess = execa.ExecaChildProcess<string>;

View File

@@ -0,0 +1,80 @@
import type { CLIProcess } from './types';
function getPromptErrorDetails(
rawAssertion: string | Function | RegExp,
mostRecentChunk: string
) {
const assertion = rawAssertion.toString().trim();
const mostRecent = (mostRecentChunk || '').trim();
return `Waiting for:\n "${assertion}"\nmost recent chunk was:\n "${mostRecent}"`;
}
export default async function waitForPrompt(
cp: CLIProcess,
rawAssertion: string | RegExp | ((chunk: string) => boolean),
timeout = 3000
) {
let assertion: (chunk: string) => boolean;
if (typeof rawAssertion === 'string') {
assertion = (chunk: string) => chunk.includes(rawAssertion);
} else if (rawAssertion instanceof RegExp) {
assertion = (chunk: string) => rawAssertion.test(chunk);
} else {
assertion = rawAssertion;
}
return new Promise<void>((resolve, reject) => {
let mostRecentChunk = 'NO CHUNKS SO FAR';
console.log('Waiting for prompt...');
const handleTimeout = setTimeout(() => {
cleanup();
const promptErrorDetails = getPromptErrorDetails(
rawAssertion,
mostRecentChunk
);
reject(
new Error(
`Timed out after ${timeout}ms in waitForPrompt. ${promptErrorDetails}`
)
);
}, timeout);
const onComplete = () => {
cleanup();
const promptErrorDetails = getPromptErrorDetails(
rawAssertion,
mostRecentChunk
);
reject(
new Error(
`Process exited before prompt was found in waitForPrompt. ${promptErrorDetails}`
)
);
};
const onData = (rawChunk: Buffer) => {
const chunk = rawChunk.toString();
mostRecentChunk = chunk;
console.log('> ' + chunk);
if (assertion(chunk)) {
cleanup();
resolve();
}
};
const cleanup = () => {
cp.stdout?.off('data', onData);
cp.stderr?.off('data', onData);
cp.off('close', onComplete);
cp.off('exit', onComplete);
clearTimeout(handleTimeout);
};
cp.stdout?.on('data', onData);
cp.stderr?.on('data', onData);
cp.on('close', onComplete);
cp.on('exit', onComplete);
});
}

1020
packages/cli/test/integration-1.test.ts vendored Normal file

File diff suppressed because it is too large Load Diff

1291
packages/cli/test/integration-2.test.ts vendored Normal file

File diff suppressed because it is too large Load Diff

1436
packages/cli/test/integration-3.test.ts vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,7 @@ import { randomBytes } from 'crypto';
import { fileNameSymbol } from '@vercel/client'; import { fileNameSymbol } from '@vercel/client';
import { client } from '../../mocks/client'; import { client } from '../../mocks/client';
import deploy from '../../../src/commands/deploy'; import deploy from '../../../src/commands/deploy';
import { setupFixture } from '../../helpers/setup-fixture'; import { setupUnitFixture } from '../../helpers/setup-unit-fixture';
import { defaultProject, useProject } from '../../mocks/project'; import { defaultProject, useProject } from '../../mocks/project';
import { useTeams } from '../../mocks/team'; import { useTeams } from '../../mocks/team';
import { useUser } from '../../mocks/user'; import { useUser } from '../../mocks/user';
@@ -39,7 +39,7 @@ describe('deploy', () => {
}); });
it('should reject deploying when `--prebuilt` is used and `vc build` failed before Builders', async () => { it('should reject deploying when `--prebuilt` is used and `vc build` failed before Builders', async () => {
const cwd = setupFixture('build-output-api-failed-before-builds'); const cwd = setupUnitFixture('build-output-api-failed-before-builds');
client.setArgv('deploy', cwd, '--prebuilt'); client.setArgv('deploy', cwd, '--prebuilt');
const exitCodePromise = deploy(client); const exitCodePromise = deploy(client);
@@ -50,7 +50,7 @@ describe('deploy', () => {
}); });
it('should reject deploying when `--prebuilt` is used and `vc build` failed within a Builder', async () => { it('should reject deploying when `--prebuilt` is used and `vc build` failed within a Builder', async () => {
const cwd = setupFixture('build-output-api-failed-within-build'); const cwd = setupUnitFixture('build-output-api-failed-within-build');
client.setArgv('deploy', cwd, '--prebuilt'); client.setArgv('deploy', cwd, '--prebuilt');
const exitCodePromise = deploy(client); const exitCodePromise = deploy(client);
@@ -70,7 +70,7 @@ describe('deploy', () => {
}); });
it('should reject deploying a directory that was built with a different target environment when `--prebuilt --prod` is used on "preview" output', async () => { it('should reject deploying a directory that was built with a different target environment when `--prebuilt --prod` is used on "preview" output', async () => {
const cwd = setupFixture('build-output-api-preview'); const cwd = setupUnitFixture('build-output-api-preview');
useUser(); useUser();
useTeams('team_dummy'); useTeams('team_dummy');
@@ -92,7 +92,7 @@ describe('deploy', () => {
}); });
it('should reject deploying a directory that was built with a different target environment when `--prebuilt` is used on "production" output', async () => { it('should reject deploying a directory that was built with a different target environment when `--prebuilt` is used on "production" output', async () => {
const cwd = setupFixture('build-output-api-production'); const cwd = setupUnitFixture('build-output-api-production');
useUser(); useUser();
useTeams('team_dummy'); useTeams('team_dummy');
@@ -141,7 +141,7 @@ describe('deploy', () => {
}); });
it('should send a tgz file when `--archive=tgz`', async () => { it('should send a tgz file when `--archive=tgz`', async () => {
const cwd = setupFixture('commands/deploy/archive'); const cwd = setupUnitFixture('commands/deploy/archive');
const originalCwd = process.cwd(); const originalCwd = process.cwd();
try { try {
process.chdir(cwd); process.chdir(cwd);
@@ -204,7 +204,7 @@ describe('deploy', () => {
}); });
it('should upload missing files', async () => { it('should upload missing files', async () => {
const cwd = setupFixture('commands/deploy/archive'); const cwd = setupUnitFixture('commands/deploy/archive');
const originalCwd = process.cwd(); const originalCwd = process.cwd();
// Add random 1mb file // Add random 1mb file

View File

@@ -1,7 +1,7 @@
import fs from 'fs-extra'; import fs from 'fs-extra';
import path from 'path'; import path from 'path';
import env from '../../../src/commands/env'; import env from '../../../src/commands/env';
import { setupFixture } from '../../helpers/setup-fixture'; import { setupUnitFixture } from '../../helpers/setup-unit-fixture';
import { client } from '../../mocks/client'; import { client } from '../../mocks/client';
import { ProjectEnvTarget, ProjectEnvType } from '@vercel-internals/types'; import { ProjectEnvTarget, ProjectEnvType } from '@vercel-internals/types';
import { defaultProject, useProject } from '../../mocks/project'; import { defaultProject, useProject } from '../../mocks/project';
@@ -11,7 +11,7 @@ import { useUser } from '../../mocks/user';
describe('env', () => { describe('env', () => {
describe('pull', () => { describe('pull', () => {
it('should handle pulling', async () => { it('should handle pulling', async () => {
const cwd = setupFixture('vercel-env-pull'); const cwd = setupUnitFixture('vercel-env-pull');
useUser(); useUser();
useTeams('team_dummy'); useTeams('team_dummy');
useProject({ useProject({
@@ -35,7 +35,7 @@ describe('env', () => {
}); });
it('should handle pulling from Preview env vars', async () => { it('should handle pulling from Preview env vars', async () => {
const cwd = setupFixture('vercel-env-pull'); const cwd = setupUnitFixture('vercel-env-pull');
useUser(); useUser();
useTeams('team_dummy'); useTeams('team_dummy');
useProject({ useProject({
@@ -70,7 +70,7 @@ describe('env', () => {
}); });
it('should handle pulling from specific Git branch', async () => { it('should handle pulling from specific Git branch', async () => {
const cwd = setupFixture('vercel-env-pull'); const cwd = setupUnitFixture('vercel-env-pull');
useUser(); useUser();
useTeams('team_dummy'); useTeams('team_dummy');
useProject({ useProject({
@@ -107,7 +107,7 @@ describe('env', () => {
}); });
it('should handle alternate filename', async () => { it('should handle alternate filename', async () => {
const cwd = setupFixture('vercel-env-pull'); const cwd = setupUnitFixture('vercel-env-pull');
useUser(); useUser();
useTeams('team_dummy'); useTeams('team_dummy');
useProject({ useProject({
@@ -131,7 +131,7 @@ describe('env', () => {
}); });
it('should use given environment', async () => { it('should use given environment', async () => {
const cwd = setupFixture('vercel-env-pull'); const cwd = setupUnitFixture('vercel-env-pull');
useUser(); useUser();
useTeams('team_dummy'); useTeams('team_dummy');
useProject({ useProject({
@@ -165,7 +165,7 @@ describe('env', () => {
}); });
it('should throw an error when it does not recognize given environment', async () => { it('should throw an error when it does not recognize given environment', async () => {
const cwd = setupFixture('vercel-env-pull'); const cwd = setupUnitFixture('vercel-env-pull');
useUser(); useUser();
useTeams('team_dummy'); useTeams('team_dummy');
useProject({ useProject({
@@ -193,7 +193,7 @@ describe('env', () => {
}); });
it('should expose production system env variables', async () => { it('should expose production system env variables', async () => {
const cwd = setupFixture('vercel-env-pull'); const cwd = setupUnitFixture('vercel-env-pull');
useUser(); useUser();
useTeams('team_dummy'); useTeams('team_dummy');
useProject({ useProject({
@@ -220,7 +220,7 @@ describe('env', () => {
}); });
it('should show a delta string', async () => { it('should show a delta string', async () => {
const cwd = setupFixture('vercel-env-pull-delta'); const cwd = setupUnitFixture('vercel-env-pull-delta');
try { try {
useUser(); useUser();
useTeams('team_dummy'); useTeams('team_dummy');
@@ -264,7 +264,7 @@ describe('env', () => {
}); });
it('should not show a delta string when it fails to read a file', async () => { it('should not show a delta string when it fails to read a file', async () => {
const cwd = setupFixture('vercel-env-pull-delta-corrupt'); const cwd = setupUnitFixture('vercel-env-pull-delta-corrupt');
useUser(); useUser();
useTeams('team_dummy'); useTeams('team_dummy');
useProject({ useProject({
@@ -280,7 +280,7 @@ describe('env', () => {
}); });
it('should show that no changes were found', async () => { it('should show that no changes were found', async () => {
const cwd = setupFixture('vercel-env-pull-delta-no-changes'); const cwd = setupUnitFixture('vercel-env-pull-delta-no-changes');
useUser(); useUser();
useTeams('team_dummy'); useTeams('team_dummy');
useProject({ useProject({
@@ -297,7 +297,7 @@ describe('env', () => {
}); });
it('should correctly render delta string when env variable has quotes', async () => { it('should correctly render delta string when env variable has quotes', async () => {
const cwd = setupFixture('vercel-env-pull-delta-quotes'); const cwd = setupUnitFixture('vercel-env-pull-delta-quotes');
try { try {
useUser(); useUser();
useTeams('team_dummy'); useTeams('team_dummy');
@@ -334,7 +334,7 @@ describe('env', () => {
}); });
it('should correctly render delta string when local env variable has quotes', async () => { it('should correctly render delta string when local env variable has quotes', async () => {
const cwd = setupFixture('vercel-env-pull-delta-quotes'); const cwd = setupUnitFixture('vercel-env-pull-delta-quotes');
try { try {
useUser(); useUser();
useTeams('team_dummy'); useTeams('team_dummy');

View File

@@ -1,7 +1,7 @@
import fs from 'fs-extra'; import fs from 'fs-extra';
import path from 'path'; import path from 'path';
import pull from '../../../src/commands/pull'; import pull from '../../../src/commands/pull';
import { setupFixture } from '../../helpers/setup-fixture'; import { setupUnitFixture } from '../../helpers/setup-unit-fixture';
import { client } from '../../mocks/client'; import { client } from '../../mocks/client';
import { defaultProject, useProject } from '../../mocks/project'; import { defaultProject, useProject } from '../../mocks/project';
import { useTeams } from '../../mocks/team'; import { useTeams } from '../../mocks/team';
@@ -9,7 +9,7 @@ import { useUser } from '../../mocks/user';
describe('pull', () => { describe('pull', () => {
it('should handle pulling', async () => { it('should handle pulling', async () => {
const cwd = setupFixture('vercel-pull-next'); const cwd = setupUnitFixture('vercel-pull-next');
useUser(); useUser();
useTeams('team_dummy'); useTeams('team_dummy');
useProject({ useProject({
@@ -40,7 +40,7 @@ describe('pull', () => {
it('should fail with message to pull without a link and without --env', async () => { it('should fail with message to pull without a link and without --env', async () => {
client.stdin.isTTY = false; client.stdin.isTTY = false;
const cwd = setupFixture('vercel-pull-unlinked'); const cwd = setupUnitFixture('vercel-pull-unlinked');
useUser(); useUser();
useTeams('team_dummy'); useTeams('team_dummy');
@@ -53,7 +53,7 @@ describe('pull', () => {
}); });
it('should fail without message to pull without a link and with --env', async () => { it('should fail without message to pull without a link and with --env', async () => {
const cwd = setupFixture('vercel-pull-next'); const cwd = setupUnitFixture('vercel-pull-next');
useUser(); useUser();
useTeams('team_dummy'); useTeams('team_dummy');
@@ -70,7 +70,7 @@ describe('pull', () => {
process.env.VERCEL_PROJECT_ID = 'vercel-pull-next'; process.env.VERCEL_PROJECT_ID = 'vercel-pull-next';
process.env.VERCEL_ORG_ID = 'team_dummy'; process.env.VERCEL_ORG_ID = 'team_dummy';
const cwd = setupFixture('vercel-pull-next'); const cwd = setupUnitFixture('vercel-pull-next');
// Remove the `.vercel` dir to ensure that the `pull` // Remove the `.vercel` dir to ensure that the `pull`
// command creates a new one based on env vars // command creates a new one based on env vars
@@ -113,7 +113,7 @@ describe('pull', () => {
}); });
it('should handle --environment=preview flag', async () => { it('should handle --environment=preview flag', async () => {
const cwd = setupFixture('vercel-pull-next'); const cwd = setupUnitFixture('vercel-pull-next');
useUser(); useUser();
useTeams('team_dummy'); useTeams('team_dummy');
useProject({ useProject({
@@ -144,7 +144,7 @@ describe('pull', () => {
}); });
it('should handle --environment=production flag', async () => { it('should handle --environment=production flag', async () => {
const cwd = setupFixture('vercel-pull-next'); const cwd = setupUnitFixture('vercel-pull-next');
useUser(); useUser();
useTeams('team_dummy'); useTeams('team_dummy');
useProject({ useProject({

View File

@@ -4,7 +4,7 @@ import { defaultProject, useProject } from '../../mocks/project';
import { Request, Response } from 'express'; import { Request, Response } from 'express';
import rollback from '../../../src/commands/rollback'; import rollback from '../../../src/commands/rollback';
import { RollbackJobStatus, RollbackTarget } from '@vercel-internals/types'; import { RollbackJobStatus, RollbackTarget } from '@vercel-internals/types';
import { setupFixture } from '../../helpers/setup-fixture'; import { setupUnitFixture } from '../../helpers/setup-unit-fixture';
import { useDeployment } from '../../mocks/deployment'; import { useDeployment } from '../../mocks/deployment';
import { useTeams } from '../../mocks/team'; import { useTeams } from '../../mocks/team';
import { useUser } from '../../mocks/user'; import { useUser } from '../../mocks/user';
@@ -307,7 +307,7 @@ function initRollbackTest({
rollbackPollCount?: number; rollbackPollCount?: number;
rollbackStatusCode?: number; rollbackStatusCode?: number;
} = {}) { } = {}) {
const cwd = setupFixture('vercel-rollback'); const cwd = setupUnitFixture('vercel-rollback');
const user = useUser(); const user = useUser();
useTeams('team_dummy'); useTeams('team_dummy');
const { project } = useProject({ const { project } = useProject({

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/client", "name": "@vercel/client",
"version": "12.4.6", "version": "12.4.8",
"main": "dist/index.js", "main": "dist/index.js",
"typings": "dist/index.d.ts", "typings": "dist/index.d.ts",
"homepage": "https://vercel.com", "homepage": "https://vercel.com",
@@ -43,7 +43,7 @@
] ]
}, },
"dependencies": { "dependencies": {
"@vercel/build-utils": "6.5.0", "@vercel/build-utils": "6.7.0",
"@vercel/routing-utils": "2.1.11", "@vercel/routing-utils": "2.1.11",
"@zeit/fetch": "5.2.0", "@zeit/fetch": "5.2.0",
"async-retry": "1.2.3", "async-retry": "1.2.3",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/fs-detectors", "name": "@vercel/fs-detectors",
"version": "3.8.6", "version": "3.8.8",
"description": "Vercel filesystem detectors", "description": "Vercel filesystem detectors",
"main": "./dist/index.js", "main": "./dist/index.js",
"types": "./dist/index.d.ts", "types": "./dist/index.d.ts",
@@ -35,7 +35,7 @@
"@types/minimatch": "3.0.5", "@types/minimatch": "3.0.5",
"@types/node": "14.18.33", "@types/node": "14.18.33",
"@types/semver": "7.3.10", "@types/semver": "7.3.10",
"@vercel/build-utils": "6.5.0", "@vercel/build-utils": "6.7.0",
"typescript": "4.3.4" "typescript": "4.3.4"
} }
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/gatsby-plugin-vercel-builder", "name": "@vercel/gatsby-plugin-vercel-builder",
"version": "1.2.4", "version": "1.2.6",
"main": "dist/index.js", "main": "dist/index.js",
"files": [ "files": [
"dist", "dist",
@@ -15,8 +15,8 @@
}, },
"dependencies": { "dependencies": {
"@sinclair/typebox": "0.25.24", "@sinclair/typebox": "0.25.24",
"@vercel/build-utils": "6.5.0", "@vercel/build-utils": "6.7.0",
"@vercel/node": "2.10.0", "@vercel/node": "2.10.2",
"@vercel/routing-utils": "2.1.11", "@vercel/routing-utils": "2.1.11",
"esbuild": "0.14.47", "esbuild": "0.14.47",
"etag": "1.8.1", "etag": "1.8.1",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/go", "name": "@vercel/go",
"version": "2.4.1", "version": "2.4.3",
"license": "MIT", "license": "MIT",
"main": "./dist/index", "main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/go", "homepage": "https://vercel.com/docs/runtimes#official-runtimes/go",
@@ -37,7 +37,7 @@
"@types/node-fetch": "^2.3.0", "@types/node-fetch": "^2.3.0",
"@types/tar": "^4.0.0", "@types/tar": "^4.0.0",
"@types/yauzl-promise": "2.1.0", "@types/yauzl-promise": "2.1.0",
"@vercel/build-utils": "6.5.0", "@vercel/build-utils": "6.7.0",
"@vercel/ncc": "0.24.0", "@vercel/ncc": "0.24.0",
"async-retry": "1.3.1", "async-retry": "1.3.1",
"execa": "^1.0.0", "execa": "^1.0.0",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/hydrogen", "name": "@vercel/hydrogen",
"version": "0.0.59", "version": "0.0.61",
"license": "MIT", "license": "MIT",
"main": "./dist/index.js", "main": "./dist/index.js",
"homepage": "https://vercel.com/docs", "homepage": "https://vercel.com/docs",
@@ -21,7 +21,7 @@
"devDependencies": { "devDependencies": {
"@types/jest": "27.5.1", "@types/jest": "27.5.1",
"@types/node": "14.18.33", "@types/node": "14.18.33",
"@vercel/build-utils": "6.5.0", "@vercel/build-utils": "6.7.0",
"@vercel/static-config": "2.0.14", "@vercel/static-config": "2.0.14",
"execa": "3.2.0", "execa": "3.2.0",
"fs-extra": "11.1.0", "fs-extra": "11.1.0",

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/next", "name": "@vercel/next",
"version": "3.7.1", "version": "3.7.3",
"license": "MIT", "license": "MIT",
"main": "./dist/index", "main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/next-js", "homepage": "https://vercel.com/docs/runtimes#official-runtimes/next-js",
@@ -45,7 +45,7 @@
"@types/semver": "6.0.0", "@types/semver": "6.0.0",
"@types/text-table": "0.2.1", "@types/text-table": "0.2.1",
"@types/webpack-sources": "3.2.0", "@types/webpack-sources": "3.2.0",
"@vercel/build-utils": "6.5.0", "@vercel/build-utils": "6.7.0",
"@vercel/nft": "0.22.5", "@vercel/nft": "0.22.5",
"@vercel/routing-utils": "2.1.11", "@vercel/routing-utils": "2.1.11",
"async-sema": "3.0.1", "async-sema": "3.0.1",

View File

@@ -795,7 +795,7 @@ export async function createLambdaFromPseudoLayers({
...lambdaOptions, ...lambdaOptions,
...(isStreaming ...(isStreaming
? { ? {
experimentalResponseStreaming: true, supportsResponseStreaming: true,
} }
: {}), : {}),
files, files,

View File

@@ -35,7 +35,7 @@ if (parseInt(process.versions.node.split('.')[0], 10) >= 16) {
expect(buildResult.output['api/hello-again']).toBeDefined(); expect(buildResult.output['api/hello-again']).toBeDefined();
expect(buildResult.output['api/hello-again'].type).toBe('Lambda'); expect(buildResult.output['api/hello-again'].type).toBe('Lambda');
expect( expect(
buildResult.output['api/hello-again'].experimentalResponseStreaming buildResult.output['api/hello-again'].supportsResponseStreaming
).toBe(true); ).toBe(true);
expect(buildResult.output['edge-route-handler']).toBeDefined(); expect(buildResult.output['edge-route-handler']).toBeDefined();

View File

@@ -39,19 +39,20 @@ function normalizeProxyEvent(event) {
responseCallbackCipherKey, responseCallbackCipherKey,
responseCallbackStream, responseCallbackStream,
responseCallbackUrl, responseCallbackUrl,
features,
} = payload; } = payload;
/** /**
* *
* @param {string | Buffer} b * @param {string | Buffer} body
* @returns Buffer * @returns Buffer
*/ */
const normalizeBody = b => { const normalizeBody = body => {
if (b) { if (body) {
if (typeof b === 'string' && encoding === 'base64') { if (typeof body === 'string' && encoding === 'base64') {
bodyBuffer = Buffer.from(b, encoding); bodyBuffer = Buffer.from(body, encoding);
} else if (encoding === undefined) { } else if (encoding === undefined) {
bodyBuffer = Buffer.from(b); bodyBuffer = Buffer.from(body);
} else { } else {
throw new Error(`Unsupported encoding: ${encoding}`); throw new Error(`Unsupported encoding: ${encoding}`);
} }
@@ -62,8 +63,9 @@ function normalizeProxyEvent(event) {
}; };
if (payloads) { if (payloads) {
for (const p of payloads) { for (const targetPayload of payloads) {
p.body = normalizeBody(payload.body); targetPayload.features = features;
targetPayload.body = normalizeBody(payload.body);
} }
} }
bodyBuffer = normalizeBody(body); bodyBuffer = normalizeBody(body);
@@ -75,6 +77,7 @@ function normalizeProxyEvent(event) {
headers, headers,
body: bodyBuffer, body: bodyBuffer,
payloads, payloads,
features,
responseCallbackCipher, responseCallbackCipher,
responseCallbackCipherIV, responseCallbackCipherIV,
responseCallbackCipherKey, responseCallbackCipherKey,
@@ -84,50 +87,12 @@ function normalizeProxyEvent(event) {
} }
/** /**
* @param {import('aws-lambda').APIGatewayProxyEvent} event * @param {import('./types').VercelProxyEvent } event
*/ * @return {import('./types').VercelProxyRequest }
function normalizeAPIGatewayProxyEvent(event) {
let bodyBuffer;
const { httpMethod: method, path, headers, body } = event;
if (body) {
if (event.isBase64Encoded) {
bodyBuffer = Buffer.from(body, 'base64');
} else {
bodyBuffer = Buffer.from(body);
}
} else {
bodyBuffer = Buffer.alloc(0);
}
return {
body: bodyBuffer,
headers,
isApiGateway: true,
method,
path,
responseCallbackCipher: undefined,
responseCallbackCipherIV: undefined,
responseCallbackCipherKey: undefined,
responseCallbackStream: undefined,
responseCallbackUrl: undefined,
};
}
/**
* @param {import('./types').VercelProxyEvent | import('aws-lambda').APIGatewayProxyEvent} event
* @return {import('./types').VercelProxyRequest}
*/ */
function normalizeEvent(event) { function normalizeEvent(event) {
if ('Action' in event) { if (event.Action === 'Invoke') return normalizeProxyEvent(event);
if (event.Action === 'Invoke') {
return normalizeProxyEvent(event);
} else {
throw new Error(`Unexpected event.Action: ${event.Action}`); throw new Error(`Unexpected event.Action: ${event.Action}`);
}
} else {
return normalizeAPIGatewayProxyEvent(event);
}
} }
class Bridge { class Bridge {
@@ -207,7 +172,7 @@ class Bridge {
/** /**
* *
* @param {import('./types').VercelProxyEvent | import('aws-lambda').APIGatewayProxyEvent} event * @param {import('./types').VercelProxyEvent} event
* @param {import('aws-lambda').Context} context * @param {import('aws-lambda').Context} context
* @return {Promise<import('./types').VercelProxyResponse>} * @return {Promise<import('./types').VercelProxyResponse>}
*/ */

View File

@@ -153,17 +153,17 @@ function getAwsLauncher({ entrypointPath, awsLambdaHandler = '' }) {
} }
/** /**
* @param {import('aws-lambda').APIGatewayProxyEvent} e * @param {import('aws-lambda').APIGatewayProxyEvent} event
* @param {import('aws-lambda').Context} context * @param {import('aws-lambda').Context} context
* @param {() => void} callback * @param {() => void} callback
*/ */
function internal(e, context, callback) { function internal(event, context, callback) {
const { const {
path, path,
method: httpMethod, method: httpMethod,
body, body,
headers, headers,
} = JSON.parse(e.body || '{}'); } = JSON.parse(event.body || '{}');
const { query } = parse(path, true); const { query } = parse(path, true);
/** /**
* @type {{[key: string]: string}} * @type {{[key: string]: string}}

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/node-bridge", "name": "@vercel/node-bridge",
"version": "3.1.14", "version": "4.0.0",
"license": "MIT", "license": "MIT",
"main": "./index.js", "main": "./index.js",
"repository": { "repository": {

View File

@@ -19,39 +19,6 @@ test('port binding', async () => {
server.close(); server.close();
}); });
test('`APIGatewayProxyEvent` normalizing', async () => {
const server = new Server((req, res) =>
res.end(
JSON.stringify({
method: req.method,
path: req.url,
headers: req.headers,
})
)
);
const bridge = new Bridge(server);
bridge.listen();
const context = {};
const result = await bridge.launcher(
{
httpMethod: 'GET',
headers: { foo: 'bar' },
path: '/apigateway',
body: null,
},
context
);
assert.strictEqual(result.encoding, 'base64');
assert.strictEqual(result.statusCode, 200);
const body = JSON.parse(Buffer.from(result.body, 'base64').toString());
assert.strictEqual(body.method, 'GET');
assert.strictEqual(body.path, '/apigateway');
assert.strictEqual(body.headers.foo, 'bar');
assert.strictEqual(context.callbackWaitsForEmptyEventLoop, false);
server.close();
});
test('`NowProxyEvent` normalizing', async () => { test('`NowProxyEvent` normalizing', async () => {
const server = new Server((req, res) => const server = new Server((req, res) =>
res.end( res.end(
@@ -62,8 +29,19 @@ test('`NowProxyEvent` normalizing', async () => {
}) })
) )
); );
const bridge = new Bridge(server);
let features;
class CustomBridge extends Bridge {
handleEvent(normalizedEvent) {
features = normalizedEvent.features;
return super.handleEvent(normalizedEvent);
}
}
const bridge = new CustomBridge(server);
bridge.listen(); bridge.listen();
const context = { callbackWaitsForEmptyEventLoop: true }; const context = { callbackWaitsForEmptyEventLoop: true };
const result = await bridge.launcher( const result = await bridge.launcher(
{ {
@@ -71,12 +49,14 @@ test('`NowProxyEvent` normalizing', async () => {
body: JSON.stringify({ body: JSON.stringify({
method: 'POST', method: 'POST',
headers: { foo: 'baz' }, headers: { foo: 'baz' },
features: { enabled: true },
path: '/nowproxy', path: '/nowproxy',
body: 'body=1', body: 'body=1',
}), }),
}, },
context context
); );
assert.deepStrictEqual(features, { enabled: true });
assert.strictEqual(result.encoding, 'base64'); assert.strictEqual(result.encoding, 'base64');
assert.strictEqual(result.statusCode, 200); assert.strictEqual(result.statusCode, 200);
const body = JSON.parse(Buffer.from(result.body, 'base64').toString()); const body = JSON.parse(Buffer.from(result.body, 'base64').toString());

View File

@@ -19,6 +19,7 @@ export interface VercelProxyRequest {
body: Buffer; body: Buffer;
encoding?: string; encoding?: string;
payloads?: Array<VercelProxyRequest>; payloads?: Array<VercelProxyRequest>;
features?: Record<string, boolean>;
responseCallbackCipher?: CipherCCMTypes; responseCallbackCipher?: CipherCCMTypes;
responseCallbackCipherIV?: string; responseCallbackCipherIV?: string;
responseCallbackCipherKey?: string; responseCallbackCipherKey?: string;

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/node", "name": "@vercel/node",
"version": "2.10.0", "version": "2.10.2",
"license": "MIT", "license": "MIT",
"main": "./dist/index", "main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/node-js", "homepage": "https://vercel.com/docs/runtimes#official-runtimes/node-js",
@@ -31,8 +31,8 @@
"dependencies": { "dependencies": {
"@edge-runtime/vm": "2.0.0", "@edge-runtime/vm": "2.0.0",
"@types/node": "14.18.33", "@types/node": "14.18.33",
"@vercel/build-utils": "6.5.0", "@vercel/build-utils": "6.7.0",
"@vercel/node-bridge": "3.1.14", "@vercel/node-bridge": "4.0.0",
"@vercel/static-config": "2.0.14", "@vercel/static-config": "2.0.14",
"edge-runtime": "2.0.0", "edge-runtime": "2.0.0",
"esbuild": "0.14.47", "esbuild": "0.14.47",

View File

@@ -93,7 +93,7 @@ async function main() {
handleEvent = await createEventHandler(entrypoint!, config, { handleEvent = await createEventHandler(entrypoint!, config, {
shouldAddHelpers, shouldAddHelpers,
}); });
} catch (error) { } catch (error: any) {
logError(error); logError(error);
handlerEventError = error; handlerEventError = error;
} }
@@ -132,7 +132,7 @@ export async function onDevRequest(
} }
} }
res.end(Buffer.from(result.body, result.encoding)); res.end(Buffer.from(result.body, result.encoding));
} catch (error) { } catch (error: any) {
res.statusCode = 500; res.statusCode = 500;
res.end(error.stack); res.end(error.stack);
} }

View File

@@ -487,8 +487,11 @@ export const build: BuildV3 = async ({
config.helpers === false || process.env.NODEJS_HELPERS === '0' config.helpers === false || process.env.NODEJS_HELPERS === '0'
); );
const experimentalResponseStreaming = const supportsResponseStreaming =
staticConfig?.experimentalResponseStreaming === true ? true : undefined; (staticConfig?.supportsResponseStreaming ??
staticConfig?.experimentalResponseStreaming) === true
? true
: undefined;
output = new NodejsLambda({ output = new NodejsLambda({
files: preparedFiles, files: preparedFiles,
@@ -497,7 +500,7 @@ export const build: BuildV3 = async ({
shouldAddHelpers, shouldAddHelpers,
shouldAddSourcemapSupport, shouldAddSourcemapSupport,
awsLambdaHandler, awsLambdaHandler,
experimentalResponseStreaming, supportsResponseStreaming,
}); });
} }

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/python", "name": "@vercel/python",
"version": "3.1.55", "version": "3.1.57",
"main": "./dist/index.js", "main": "./dist/index.js",
"license": "MIT", "license": "MIT",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/python", "homepage": "https://vercel.com/docs/runtimes#official-runtimes/python",
@@ -23,7 +23,7 @@
"@types/execa": "^0.9.0", "@types/execa": "^0.9.0",
"@types/jest": "27.4.1", "@types/jest": "27.4.1",
"@types/node": "14.18.33", "@types/node": "14.18.33",
"@vercel/build-utils": "6.5.0", "@vercel/build-utils": "6.7.0",
"@vercel/ncc": "0.24.0", "@vercel/ncc": "0.24.0",
"execa": "^1.0.0", "execa": "^1.0.0",
"typescript": "4.3.4" "typescript": "4.3.4"

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/redwood", "name": "@vercel/redwood",
"version": "1.1.11", "version": "1.1.13",
"main": "./dist/index.js", "main": "./dist/index.js",
"license": "MIT", "license": "MIT",
"homepage": "https://vercel.com/docs", "homepage": "https://vercel.com/docs",
@@ -27,7 +27,7 @@
"@types/aws-lambda": "8.10.19", "@types/aws-lambda": "8.10.19",
"@types/node": "14.18.33", "@types/node": "14.18.33",
"@types/semver": "6.0.0", "@types/semver": "6.0.0",
"@vercel/build-utils": "6.5.0", "@vercel/build-utils": "6.7.0",
"execa": "3.2.0", "execa": "3.2.0",
"fs-extra": "11.1.0", "fs-extra": "11.1.0",
"typescript": "4.3.4" "typescript": "4.3.4"

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/remix-builder", "name": "@vercel/remix-builder",
"version": "1.8.1", "version": "1.8.3",
"license": "MIT", "license": "MIT",
"main": "./dist/index.js", "main": "./dist/index.js",
"homepage": "https://vercel.com/docs", "homepage": "https://vercel.com/docs",
@@ -21,7 +21,7 @@
], ],
"dependencies": { "dependencies": {
"@remix-run/dev": "npm:@vercel/remix-run-dev@1.14.2", "@remix-run/dev": "npm:@vercel/remix-run-dev@1.14.2",
"@vercel/build-utils": "6.5.0", "@vercel/build-utils": "6.7.0",
"@vercel/nft": "0.22.5", "@vercel/nft": "0.22.5",
"@vercel/static-config": "2.0.14", "@vercel/static-config": "2.0.14",
"path-to-regexp": "6.2.1", "path-to-regexp": "6.2.1",

View File

@@ -522,7 +522,7 @@ async function createRenderNodeFunction(
shouldAddHelpers: false, shouldAddHelpers: false,
shouldAddSourcemapSupport: false, shouldAddSourcemapSupport: false,
operationType: 'SSR', operationType: 'SSR',
experimentalResponseStreaming: true, supportsResponseStreaming: true,
regions: config.regions, regions: config.regions,
memory: config.memory, memory: config.memory,
maxDuration: config.maxDuration, maxDuration: config.maxDuration,

View File

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

View File

@@ -1,6 +1,6 @@
{ {
"name": "@vercel/static-build", "name": "@vercel/static-build",
"version": "1.3.19", "version": "1.3.21",
"license": "MIT", "license": "MIT",
"main": "./dist/index", "main": "./dist/index",
"homepage": "https://vercel.com/docs/build-step", "homepage": "https://vercel.com/docs/build-step",
@@ -30,7 +30,7 @@
}, },
"dependencies": { "dependencies": {
"@vercel/gatsby-plugin-vercel-analytics": "1.0.8", "@vercel/gatsby-plugin-vercel-analytics": "1.0.8",
"@vercel/gatsby-plugin-vercel-builder": "1.2.4" "@vercel/gatsby-plugin-vercel-builder": "1.2.6"
}, },
"devDependencies": { "devDependencies": {
"@types/aws-lambda": "8.10.64", "@types/aws-lambda": "8.10.64",
@@ -42,9 +42,9 @@
"@types/node-fetch": "2.5.4", "@types/node-fetch": "2.5.4",
"@types/promise-timeout": "1.3.0", "@types/promise-timeout": "1.3.0",
"@types/semver": "7.3.13", "@types/semver": "7.3.13",
"@vercel/build-utils": "6.5.0", "@vercel/build-utils": "6.7.0",
"@vercel/frameworks": "1.3.3", "@vercel/frameworks": "1.3.3",
"@vercel/fs-detectors": "3.8.6", "@vercel/fs-detectors": "3.8.8",
"@vercel/ncc": "0.24.0", "@vercel/ncc": "0.24.0",
"@vercel/routing-utils": "2.1.11", "@vercel/routing-utils": "2.1.11",
"@vercel/static-config": "2.0.14", "@vercel/static-config": "2.0.14",

73
pnpm-lock.yaml generated
View File

@@ -236,23 +236,23 @@ importers:
'@types/write-json-file': 2.2.1 '@types/write-json-file': 2.2.1
'@types/yauzl-promise': 2.1.0 '@types/yauzl-promise': 2.1.0
'@vercel-internals/types': '*' '@vercel-internals/types': '*'
'@vercel/build-utils': 6.5.0 '@vercel/build-utils': 6.7.0
'@vercel/client': 12.4.6 '@vercel/client': 12.4.8
'@vercel/error-utils': 1.0.8 '@vercel/error-utils': 1.0.8
'@vercel/frameworks': 1.3.3 '@vercel/frameworks': 1.3.3
'@vercel/fs-detectors': 3.8.6 '@vercel/fs-detectors': 3.8.8
'@vercel/fun': 1.0.4 '@vercel/fun': 1.0.4
'@vercel/go': 2.4.1 '@vercel/go': 2.4.3
'@vercel/hydrogen': 0.0.59 '@vercel/hydrogen': 0.0.61
'@vercel/ncc': 0.24.0 '@vercel/ncc': 0.24.0
'@vercel/next': 3.7.1 '@vercel/next': 3.7.3
'@vercel/node': 2.10.0 '@vercel/node': 2.10.2
'@vercel/python': 3.1.55 '@vercel/python': 3.1.57
'@vercel/redwood': 1.1.11 '@vercel/redwood': 1.1.13
'@vercel/remix-builder': 1.8.1 '@vercel/remix-builder': 1.8.3
'@vercel/routing-utils': 2.1.11 '@vercel/routing-utils': 2.1.11
'@vercel/ruby': 1.3.72 '@vercel/ruby': 1.3.74
'@vercel/static-build': 1.3.19 '@vercel/static-build': 1.3.21
'@zeit/source-map-support': 0.6.2 '@zeit/source-map-support': 0.6.2
ajv: 6.12.2 ajv: 6.12.2
alpha-sort: 2.0.1 alpha-sort: 2.0.1
@@ -475,7 +475,7 @@ importers:
'@types/node-fetch': 2.5.4 '@types/node-fetch': 2.5.4
'@types/recursive-readdir': 2.2.0 '@types/recursive-readdir': 2.2.0
'@types/tar-fs': 1.16.1 '@types/tar-fs': 1.16.1
'@vercel/build-utils': 6.5.0 '@vercel/build-utils': 6.7.0
'@vercel/routing-utils': 2.1.11 '@vercel/routing-utils': 2.1.11
'@zeit/fetch': 5.2.0 '@zeit/fetch': 5.2.0
async-retry: 1.2.3 async-retry: 1.2.3
@@ -580,7 +580,7 @@ importers:
'@types/minimatch': 3.0.5 '@types/minimatch': 3.0.5
'@types/node': 14.18.33 '@types/node': 14.18.33
'@types/semver': 7.3.10 '@types/semver': 7.3.10
'@vercel/build-utils': 6.5.0 '@vercel/build-utils': 6.7.0
'@vercel/error-utils': 1.0.8 '@vercel/error-utils': 1.0.8
'@vercel/frameworks': 1.3.3 '@vercel/frameworks': 1.3.3
'@vercel/routing-utils': 2.1.11 '@vercel/routing-utils': 2.1.11
@@ -629,8 +629,8 @@ importers:
'@types/fs-extra': 11.0.1 '@types/fs-extra': 11.0.1
'@types/node': 14.18.33 '@types/node': 14.18.33
'@types/react': 18.0.26 '@types/react': 18.0.26
'@vercel/build-utils': 6.5.0 '@vercel/build-utils': 6.7.0
'@vercel/node': 2.10.0 '@vercel/node': 2.10.2
'@vercel/routing-utils': 2.1.11 '@vercel/routing-utils': 2.1.11
esbuild: 0.14.47 esbuild: 0.14.47
etag: 1.8.1 etag: 1.8.1
@@ -662,7 +662,7 @@ importers:
'@types/node-fetch': ^2.3.0 '@types/node-fetch': ^2.3.0
'@types/tar': ^4.0.0 '@types/tar': ^4.0.0
'@types/yauzl-promise': 2.1.0 '@types/yauzl-promise': 2.1.0
'@vercel/build-utils': 6.5.0 '@vercel/build-utils': 6.7.0
'@vercel/ncc': 0.24.0 '@vercel/ncc': 0.24.0
async-retry: 1.3.1 async-retry: 1.3.1
execa: ^1.0.0 execa: ^1.0.0
@@ -699,7 +699,7 @@ importers:
specifiers: specifiers:
'@types/jest': 27.5.1 '@types/jest': 27.5.1
'@types/node': 14.18.33 '@types/node': 14.18.33
'@vercel/build-utils': 6.5.0 '@vercel/build-utils': 6.7.0
'@vercel/static-config': 2.0.14 '@vercel/static-config': 2.0.14
execa: 3.2.0 execa: 3.2.0
fs-extra: 11.1.0 fs-extra: 11.1.0
@@ -730,7 +730,7 @@ importers:
'@types/semver': 6.0.0 '@types/semver': 6.0.0
'@types/text-table': 0.2.1 '@types/text-table': 0.2.1
'@types/webpack-sources': 3.2.0 '@types/webpack-sources': 3.2.0
'@vercel/build-utils': 6.5.0 '@vercel/build-utils': 6.7.0
'@vercel/nft': 0.22.5 '@vercel/nft': 0.22.5
'@vercel/routing-utils': 2.1.11 '@vercel/routing-utils': 2.1.11
async-sema: 3.0.1 async-sema: 3.0.1
@@ -809,10 +809,10 @@ importers:
'@types/node': 14.18.33 '@types/node': 14.18.33
'@types/node-fetch': ^2.6.1 '@types/node-fetch': ^2.6.1
'@types/test-listen': 1.1.0 '@types/test-listen': 1.1.0
'@vercel/build-utils': 6.5.0 '@vercel/build-utils': 6.7.0
'@vercel/ncc': 0.24.0 '@vercel/ncc': 0.24.0
'@vercel/nft': 0.22.5 '@vercel/nft': 0.22.5
'@vercel/node-bridge': 3.1.14 '@vercel/node-bridge': 4.0.0
'@vercel/static-config': 2.0.14 '@vercel/static-config': 2.0.14
content-type: 1.0.4 content-type: 1.0.4
cookie: 0.4.0 cookie: 0.4.0
@@ -893,7 +893,7 @@ importers:
'@types/execa': ^0.9.0 '@types/execa': ^0.9.0
'@types/jest': 27.4.1 '@types/jest': 27.4.1
'@types/node': 14.18.33 '@types/node': 14.18.33
'@vercel/build-utils': 6.5.0 '@vercel/build-utils': 6.7.0
'@vercel/ncc': 0.24.0 '@vercel/ncc': 0.24.0
execa: ^1.0.0 execa: ^1.0.0
typescript: 4.3.4 typescript: 4.3.4
@@ -911,7 +911,7 @@ importers:
'@types/aws-lambda': 8.10.19 '@types/aws-lambda': 8.10.19
'@types/node': 14.18.33 '@types/node': 14.18.33
'@types/semver': 6.0.0 '@types/semver': 6.0.0
'@vercel/build-utils': 6.5.0 '@vercel/build-utils': 6.7.0
'@vercel/nft': 0.22.5 '@vercel/nft': 0.22.5
'@vercel/routing-utils': 2.1.11 '@vercel/routing-utils': 2.1.11
execa: 3.2.0 execa: 3.2.0
@@ -937,7 +937,7 @@ importers:
'@types/jest': 27.5.1 '@types/jest': 27.5.1
'@types/node': 14.18.33 '@types/node': 14.18.33
'@types/semver': 7.3.13 '@types/semver': 7.3.13
'@vercel/build-utils': 6.5.0 '@vercel/build-utils': 6.7.0
'@vercel/nft': 0.22.5 '@vercel/nft': 0.22.5
'@vercel/static-config': 2.0.14 '@vercel/static-config': 2.0.14
path-to-regexp: 6.2.1 path-to-regexp: 6.2.1
@@ -997,7 +997,7 @@ importers:
specifiers: specifiers:
'@types/fs-extra': 8.0.0 '@types/fs-extra': 8.0.0
'@types/semver': 6.0.0 '@types/semver': 6.0.0
'@vercel/build-utils': 6.5.0 '@vercel/build-utils': 6.7.0
'@vercel/ncc': 0.24.0 '@vercel/ncc': 0.24.0
execa: 2.0.4 execa: 2.0.4
fs-extra: ^7.0.1 fs-extra: ^7.0.1
@@ -1024,11 +1024,11 @@ importers:
'@types/node-fetch': 2.5.4 '@types/node-fetch': 2.5.4
'@types/promise-timeout': 1.3.0 '@types/promise-timeout': 1.3.0
'@types/semver': 7.3.13 '@types/semver': 7.3.13
'@vercel/build-utils': 6.5.0 '@vercel/build-utils': 6.7.0
'@vercel/frameworks': 1.3.3 '@vercel/frameworks': 1.3.3
'@vercel/fs-detectors': 3.8.6 '@vercel/fs-detectors': 3.8.8
'@vercel/gatsby-plugin-vercel-analytics': 1.0.8 '@vercel/gatsby-plugin-vercel-analytics': 1.0.8
'@vercel/gatsby-plugin-vercel-builder': 1.2.4 '@vercel/gatsby-plugin-vercel-builder': 1.2.6
'@vercel/ncc': 0.24.0 '@vercel/ncc': 0.24.0
'@vercel/routing-utils': 2.1.11 '@vercel/routing-utils': 2.1.11
'@vercel/static-config': 2.0.14 '@vercel/static-config': 2.0.14
@@ -2676,7 +2676,7 @@ packages:
engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0}
dependencies: dependencies:
'@jest/types': 28.1.3 '@jest/types': 28.1.3
'@types/node': 18.14.6 '@types/node': 16.18.11
chalk: 4.1.0 chalk: 4.1.0
jest-message-util: 28.1.3 jest-message-util: 28.1.3
jest-util: 28.1.3 jest-util: 28.1.3
@@ -2896,7 +2896,7 @@ packages:
'@jest/transform': 28.1.3 '@jest/transform': 28.1.3
'@jest/types': 28.1.3 '@jest/types': 28.1.3
'@jridgewell/trace-mapping': 0.3.17 '@jridgewell/trace-mapping': 0.3.17
'@types/node': 18.14.6 '@types/node': 16.18.11
chalk: 4.1.0 chalk: 4.1.0
collect-v8-coverage: 1.0.1 collect-v8-coverage: 1.0.1
exit: 0.1.2 exit: 0.1.2
@@ -3081,7 +3081,7 @@ packages:
'@jest/schemas': 28.1.3 '@jest/schemas': 28.1.3
'@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-lib-coverage': 2.0.4
'@types/istanbul-reports': 3.0.1 '@types/istanbul-reports': 3.0.1
'@types/node': 18.14.6 '@types/node': 16.18.11
'@types/yargs': 17.0.19 '@types/yargs': 17.0.19
chalk: 4.1.0 chalk: 4.1.0
dev: true dev: true
@@ -8197,7 +8197,7 @@ packages:
supports-color: supports-color:
optional: true optional: true
dependencies: dependencies:
ms: 2.1.3 ms: 2.1.2
dev: true dev: true
/debug/4.1.1: /debug/4.1.1:
@@ -11169,7 +11169,7 @@ packages:
/humanize-ms/1.2.1: /humanize-ms/1.2.1:
resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==}
dependencies: dependencies:
ms: 2.1.3 ms: 2.1.2
dev: false dev: false
/husky/7.0.4: /husky/7.0.4:
@@ -12307,7 +12307,7 @@ packages:
dependencies: dependencies:
'@jest/types': 28.1.3 '@jest/types': 28.1.3
'@types/graceful-fs': 4.1.6 '@types/graceful-fs': 4.1.6
'@types/node': 18.14.6 '@types/node': 16.18.11
anymatch: 3.1.3 anymatch: 3.1.3
fb-watchman: 2.0.2 fb-watchman: 2.0.2
graceful-fs: 4.2.10 graceful-fs: 4.2.10
@@ -12525,7 +12525,7 @@ packages:
'@jest/test-result': 28.1.3 '@jest/test-result': 28.1.3
'@jest/transform': 28.1.3 '@jest/transform': 28.1.3
'@jest/types': 28.1.3 '@jest/types': 28.1.3
'@types/node': 18.14.6 '@types/node': 16.18.11
chalk: 4.1.0 chalk: 4.1.0
emittery: 0.10.2 emittery: 0.10.2
graceful-fs: 4.2.10 graceful-fs: 4.2.10
@@ -12751,7 +12751,7 @@ packages:
dependencies: dependencies:
'@jest/test-result': 28.1.3 '@jest/test-result': 28.1.3
'@jest/types': 28.1.3 '@jest/types': 28.1.3
'@types/node': 18.14.6 '@types/node': 16.18.11
ansi-escapes: 4.3.2 ansi-escapes: 4.3.2
chalk: 4.1.0 chalk: 4.1.0
emittery: 0.10.2 emittery: 0.10.2
@@ -14232,6 +14232,7 @@ packages:
/ms/2.1.3: /ms/2.1.3:
resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
dev: true
/multimatch/5.0.0: /multimatch/5.0.0:
resolution: {integrity: sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==} resolution: {integrity: sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==}