mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-11 04:22:13 +00:00
Compare commits
23 Commits
vercel@28.
...
@vercel/py
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d5537500d8 | ||
|
|
4b1736b2f2 | ||
|
|
9da1c6fa66 | ||
|
|
a6c320846e | ||
|
|
4973814978 | ||
|
|
f1289ff263 | ||
|
|
3ff93279cd | ||
|
|
58f9d649a8 | ||
|
|
cadc082ad1 | ||
|
|
2906d83eae | ||
|
|
675c3e2915 | ||
|
|
13a8a7dbf6 | ||
|
|
b480e632a3 | ||
|
|
bc6c364888 | ||
|
|
6cad10c899 | ||
|
|
0d78ec4666 | ||
|
|
b05d653cf1 | ||
|
|
5a38b94de2 | ||
|
|
6668d6cf21 | ||
|
|
b63f444abd | ||
|
|
9d71d4332f | ||
|
|
151db21a2f | ||
|
|
aba9c95ea2 |
4
.github/CODEOWNERS
vendored
4
.github/CODEOWNERS
vendored
@@ -6,10 +6,12 @@
|
||||
/packages/cli/src/commands/domains @mglagola @anatrajkovska
|
||||
/packages/cli/src/commands/certs @mglagola @anatrajkovska
|
||||
/packages/cli/src/commands/env @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood
|
||||
/packages/middleware @gdborton @javivelasco @Schniz
|
||||
/packages/fs-detectors @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @agadzik @chloetedder
|
||||
/packages/middleware @gdborton @vercel/edge-function
|
||||
/packages/node-bridge @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @ijjk
|
||||
/packages/next @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @ijjk
|
||||
/packages/routing-utils @TooTallNate @EndangeredMassa @styfle @cb1kenobi @Ethan-Arrowood @ijjk
|
||||
/packages/edge @vercel/edge-function
|
||||
/examples @leerob
|
||||
/examples/create-react-app @Timer
|
||||
/examples/nextjs @timneutkens @ijjk @styfle
|
||||
|
||||
22
.github/workflows/required-pr-label.yml
vendored
Normal file
22
.github/workflows/required-pr-label.yml
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
name: Required PR Label
|
||||
on:
|
||||
pull_request:
|
||||
types: [opened, labeled, unlabeled, synchronize]
|
||||
jobs:
|
||||
label:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Check PR Labels
|
||||
uses: actions/github-script@v6
|
||||
with:
|
||||
script: |
|
||||
const labels = context.payload.pull_request.labels.map(l => l.name);
|
||||
if (labels.filter(l => l.startsWith('area:')).length === 0) {
|
||||
console.error('\u001b[31mMissing label: Please add at least one "area" label.');
|
||||
process.exit(1);
|
||||
}
|
||||
if (labels.filter(l => l.startsWith('semver:')).length !== 1) {
|
||||
console.error('\u001b[31mMissing label: Please add exactly one "semver" label.');
|
||||
process.exit(1);
|
||||
}
|
||||
console.log('\u001b[32mSuccess: This pull request has correct labels, thanks!');
|
||||
@@ -1,7 +1,7 @@
|
||||
version = 1
|
||||
|
||||
[merge]
|
||||
automerge_label = ["semver-major","semver-minor","semver-patch"]
|
||||
automerge_label = ["pr: automerge"]
|
||||
blacklist_title_regex = "^WIP.*"
|
||||
blacklist_labels = ["work in progress"]
|
||||
method = "squash"
|
||||
|
||||
@@ -8,7 +8,10 @@
|
||||
"packages/*"
|
||||
],
|
||||
"nohoist": [
|
||||
"**/@types/**"
|
||||
"**/@types/**",
|
||||
"**/typedoc",
|
||||
"**/typedoc-plugin-markdown",
|
||||
"**/typedoc-plugin-mdn-links"
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/build-utils",
|
||||
"version": "5.4.0",
|
||||
"version": "5.4.2",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.js",
|
||||
|
||||
@@ -23,8 +23,7 @@ export interface ScanParentDirsResult {
|
||||
*/
|
||||
cliType: CliType;
|
||||
/**
|
||||
* The file path of found `package.json` file, or `undefined` if none was
|
||||
* found.
|
||||
* The file path of found `package.json` file, or `undefined` if not found.
|
||||
*/
|
||||
packageJsonPath?: string;
|
||||
/**
|
||||
@@ -33,8 +32,13 @@ export interface ScanParentDirsResult {
|
||||
*/
|
||||
packageJson?: PackageJson;
|
||||
/**
|
||||
* The `lockfileVersion` number from the `package-lock.json` file,
|
||||
* when present.
|
||||
* The file path of the lockfile (`yarn.lock`, `package-lock.json`, or `pnpm-lock.yaml`)
|
||||
* or `undefined` if not found.
|
||||
*/
|
||||
lockfilePath?: string;
|
||||
/**
|
||||
* The `lockfileVersion` number from lockfile (`package-lock.json` or `pnpm-lock.yaml`),
|
||||
* or `undefined` if not found.
|
||||
*/
|
||||
lockfileVersion?: number;
|
||||
}
|
||||
@@ -178,25 +182,9 @@ export async function getNodeBinPath({
|
||||
}: {
|
||||
cwd: string;
|
||||
}): Promise<string> {
|
||||
const { code, stdout, stderr } = await execAsync('npm', ['bin'], {
|
||||
cwd,
|
||||
prettyCommand: 'npm bin',
|
||||
|
||||
// in some rare cases, we saw `npm bin` exit with a non-0 code, but still
|
||||
// output the right bin path, so we ignore the exit code
|
||||
ignoreNon0Exit: true,
|
||||
});
|
||||
|
||||
const nodeBinPath = stdout.trim();
|
||||
|
||||
if (path.isAbsolute(nodeBinPath)) {
|
||||
return nodeBinPath;
|
||||
}
|
||||
|
||||
throw new NowBuildError({
|
||||
code: `BUILD_UTILS_GET_NODE_BIN_PATH`,
|
||||
message: `Running \`npm bin\` failed to return a valid bin path (code=${code}, stdout=${stdout}, stderr=${stderr})`,
|
||||
});
|
||||
const { lockfilePath } = await scanParentDirs(cwd);
|
||||
const dir = path.dirname(lockfilePath || cwd);
|
||||
return path.join(dir, 'node_modules', '.bin');
|
||||
}
|
||||
|
||||
async function chmodPlusX(fsPath: string) {
|
||||
@@ -319,6 +307,7 @@ export async function scanParentDirs(
|
||||
start: destPath,
|
||||
filenames: ['yarn.lock', 'package-lock.json', 'pnpm-lock.yaml'],
|
||||
});
|
||||
let lockfilePath: string | undefined;
|
||||
let lockfileVersion: number | undefined;
|
||||
let cliType: CliType = 'yarn';
|
||||
|
||||
@@ -335,17 +324,25 @@ export async function scanParentDirs(
|
||||
// Priority order is Yarn > pnpm > npm
|
||||
if (hasYarnLock) {
|
||||
cliType = 'yarn';
|
||||
lockfilePath = yarnLockPath;
|
||||
} else if (pnpmLockYaml) {
|
||||
cliType = 'pnpm';
|
||||
// just ensure that it is read as a number and not a string
|
||||
lockfilePath = pnpmLockPath;
|
||||
lockfileVersion = Number(pnpmLockYaml.lockfileVersion);
|
||||
} else if (packageLockJson) {
|
||||
cliType = 'npm';
|
||||
lockfilePath = npmLockPath;
|
||||
lockfileVersion = packageLockJson.lockfileVersion;
|
||||
}
|
||||
|
||||
const packageJsonPath = pkgJsonPath || undefined;
|
||||
return { cliType, packageJson, lockfileVersion, packageJsonPath };
|
||||
return {
|
||||
cliType,
|
||||
packageJson,
|
||||
lockfilePath,
|
||||
lockfileVersion,
|
||||
packageJsonPath,
|
||||
};
|
||||
}
|
||||
|
||||
export async function walkParentDirs({
|
||||
|
||||
@@ -41,6 +41,7 @@ export interface Config {
|
||||
devCommand?: string;
|
||||
framework?: string | null;
|
||||
nodeVersion?: string;
|
||||
middleware?: boolean;
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
|
||||
46
packages/build-utils/test/unit.get-npm-bin-path.test.ts
vendored
Normal file
46
packages/build-utils/test/unit.get-npm-bin-path.test.ts
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
import { join, parse } from 'path';
|
||||
import { getNodeBinPath } from '../src';
|
||||
|
||||
describe('Test `getNodeBinPath()`', () => {
|
||||
it('should work with npm7', async () => {
|
||||
const cwd = join(__dirname, 'fixtures', '20-npm-7');
|
||||
const result = await getNodeBinPath({ cwd });
|
||||
expect(result).toBe(join(cwd, 'node_modules', '.bin'));
|
||||
});
|
||||
|
||||
it('should work with yarn', async () => {
|
||||
const cwd = join(__dirname, 'fixtures', '19-yarn-v2');
|
||||
const result = await getNodeBinPath({ cwd });
|
||||
expect(result).toBe(join(cwd, 'node_modules', '.bin'));
|
||||
});
|
||||
|
||||
it('should work with npm 6', async () => {
|
||||
const cwd = join(__dirname, 'fixtures', '08-yarn-npm/with-npm');
|
||||
const result = await getNodeBinPath({ cwd });
|
||||
expect(result).toBe(join(cwd, 'node_modules', '.bin'));
|
||||
});
|
||||
|
||||
it('should work with npm workspaces', async () => {
|
||||
const cwd = join(__dirname, 'fixtures', '21-npm-workspaces/a');
|
||||
const result = await getNodeBinPath({ cwd });
|
||||
expect(result).toBe(join(cwd, '..', 'node_modules', '.bin'));
|
||||
});
|
||||
|
||||
it('should work with pnpm', async () => {
|
||||
const cwd = join(__dirname, 'fixtures', '22-pnpm');
|
||||
const result = await getNodeBinPath({ cwd });
|
||||
expect(result).toBe(join(cwd, 'node_modules', '.bin'));
|
||||
});
|
||||
|
||||
it('should work with pnpm workspaces', async () => {
|
||||
const cwd = join(__dirname, 'fixtures', '23-pnpm-workspaces/c');
|
||||
const result = await getNodeBinPath({ cwd });
|
||||
expect(result).toBe(join(cwd, '..', 'node_modules', '.bin'));
|
||||
});
|
||||
|
||||
it('should fallback to cwd if no lockfile found', async () => {
|
||||
const cwd = parse(process.cwd()).root;
|
||||
const result = await getNodeBinPath({ cwd });
|
||||
expect(result).toBe(join(cwd, 'node_modules', '.bin'));
|
||||
});
|
||||
});
|
||||
12
packages/build-utils/test/unit.test.ts
vendored
12
packages/build-utils/test/unit.test.ts
vendored
@@ -501,6 +501,7 @@ it('should return lockfileVersion 2 with npm7', async () => {
|
||||
const result = await scanParentDirs(fixture);
|
||||
expect(result.cliType).toEqual('npm');
|
||||
expect(result.lockfileVersion).toEqual(2);
|
||||
expect(result.lockfilePath).toEqual(path.join(fixture, 'package-lock.json'));
|
||||
expect(result.packageJsonPath).toEqual(path.join(fixture, 'package.json'));
|
||||
});
|
||||
|
||||
@@ -509,6 +510,7 @@ it('should not return lockfileVersion with yarn', async () => {
|
||||
const result = await scanParentDirs(fixture);
|
||||
expect(result.cliType).toEqual('yarn');
|
||||
expect(result.lockfileVersion).toEqual(undefined);
|
||||
expect(result.lockfilePath).toEqual(path.join(fixture, 'yarn.lock'));
|
||||
expect(result.packageJsonPath).toEqual(path.join(fixture, 'package.json'));
|
||||
});
|
||||
|
||||
@@ -517,6 +519,7 @@ it('should return lockfileVersion 1 with older versions of npm', async () => {
|
||||
const result = await scanParentDirs(fixture);
|
||||
expect(result.cliType).toEqual('npm');
|
||||
expect(result.lockfileVersion).toEqual(1);
|
||||
expect(result.lockfilePath).toEqual(path.join(fixture, 'package-lock.json'));
|
||||
expect(result.packageJsonPath).toEqual(path.join(fixture, 'package.json'));
|
||||
});
|
||||
|
||||
@@ -525,6 +528,9 @@ it('should detect npm Workspaces', async () => {
|
||||
const result = await scanParentDirs(fixture);
|
||||
expect(result.cliType).toEqual('npm');
|
||||
expect(result.lockfileVersion).toEqual(2);
|
||||
expect(result.lockfilePath).toEqual(
|
||||
path.join(fixture, '..', 'package-lock.json')
|
||||
);
|
||||
expect(result.packageJsonPath).toEqual(path.join(fixture, 'package.json'));
|
||||
});
|
||||
|
||||
@@ -533,6 +539,7 @@ it('should detect pnpm without workspace', async () => {
|
||||
const result = await scanParentDirs(fixture);
|
||||
expect(result.cliType).toEqual('pnpm');
|
||||
expect(result.lockfileVersion).toEqual(5.3);
|
||||
expect(result.lockfilePath).toEqual(path.join(fixture, 'pnpm-lock.yaml'));
|
||||
expect(result.packageJsonPath).toEqual(path.join(fixture, 'package.json'));
|
||||
});
|
||||
|
||||
@@ -541,6 +548,9 @@ it('should detect pnpm with workspaces', async () => {
|
||||
const result = await scanParentDirs(fixture);
|
||||
expect(result.cliType).toEqual('pnpm');
|
||||
expect(result.lockfileVersion).toEqual(5.3);
|
||||
expect(result.lockfilePath).toEqual(
|
||||
path.join(fixture, '..', 'pnpm-lock.yaml')
|
||||
);
|
||||
expect(result.packageJsonPath).toEqual(path.join(fixture, 'package.json'));
|
||||
});
|
||||
|
||||
@@ -552,6 +562,7 @@ it('should detect package.json in nested backend', async () => {
|
||||
const result = await scanParentDirs(fixture);
|
||||
expect(result.cliType).toEqual('yarn');
|
||||
expect(result.lockfileVersion).toEqual(undefined);
|
||||
// There is no lockfile but this test will pick up vercel/vercel/yarn.lock
|
||||
expect(result.packageJsonPath).toEqual(path.join(fixture, 'package.json'));
|
||||
});
|
||||
|
||||
@@ -563,6 +574,7 @@ it('should detect package.json in nested frontend', async () => {
|
||||
const result = await scanParentDirs(fixture);
|
||||
expect(result.cliType).toEqual('yarn');
|
||||
expect(result.lockfileVersion).toEqual(undefined);
|
||||
// There is no lockfile but this test will pick up vercel/vercel/yarn.lock
|
||||
expect(result.packageJsonPath).toEqual(path.join(fixture, 'package.json'));
|
||||
});
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vercel",
|
||||
"version": "28.2.0",
|
||||
"version": "28.2.3",
|
||||
"preferGlobal": true,
|
||||
"license": "Apache-2.0",
|
||||
"description": "The command-line interface for Vercel",
|
||||
@@ -41,16 +41,16 @@
|
||||
"node": ">= 14"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/build-utils": "5.4.0",
|
||||
"@vercel/go": "2.2.3",
|
||||
"@vercel/hydrogen": "0.0.16",
|
||||
"@vercel/next": "3.1.22",
|
||||
"@vercel/node": "2.5.11",
|
||||
"@vercel/python": "3.1.12",
|
||||
"@vercel/redwood": "1.0.20",
|
||||
"@vercel/remix": "1.0.21",
|
||||
"@vercel/ruby": "1.3.29",
|
||||
"@vercel/static-build": "1.0.20",
|
||||
"@vercel/build-utils": "5.4.2",
|
||||
"@vercel/go": "2.2.5",
|
||||
"@vercel/hydrogen": "0.0.18",
|
||||
"@vercel/next": "3.1.25",
|
||||
"@vercel/node": "2.5.14",
|
||||
"@vercel/python": "3.1.14",
|
||||
"@vercel/redwood": "1.0.23",
|
||||
"@vercel/remix": "1.0.24",
|
||||
"@vercel/ruby": "1.3.31",
|
||||
"@vercel/static-build": "1.0.22",
|
||||
"update-notifier": "5.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
@@ -85,7 +85,6 @@
|
||||
"@types/node-fetch": "2.5.10",
|
||||
"@types/npm-package-arg": "6.1.0",
|
||||
"@types/pluralize": "0.0.29",
|
||||
"@types/progress": "2.0.3",
|
||||
"@types/psl": "1.1.0",
|
||||
"@types/semver": "6.0.1",
|
||||
"@types/tar-fs": "1.16.1",
|
||||
@@ -96,9 +95,9 @@
|
||||
"@types/which": "1.3.2",
|
||||
"@types/write-json-file": "2.2.1",
|
||||
"@types/yauzl-promise": "2.1.0",
|
||||
"@vercel/client": "12.2.2",
|
||||
"@vercel/frameworks": "1.1.3",
|
||||
"@vercel/fs-detectors": "2.0.5",
|
||||
"@vercel/client": "12.2.4",
|
||||
"@vercel/frameworks": "1.1.4",
|
||||
"@vercel/fs-detectors": "3.0.0",
|
||||
"@vercel/fun": "1.0.4",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"@zeit/source-map-support": "0.6.2",
|
||||
@@ -153,7 +152,6 @@
|
||||
"ora": "3.4.0",
|
||||
"pcre-to-regexp": "1.0.0",
|
||||
"pluralize": "7.0.0",
|
||||
"progress": "2.0.3",
|
||||
"promisepipe": "3.0.0",
|
||||
"psl": "1.1.31",
|
||||
"qr-image": "3.2.0",
|
||||
|
||||
@@ -4,7 +4,7 @@ const { statSync } = require('fs');
|
||||
const pkg = require('../package');
|
||||
|
||||
function error(command) {
|
||||
console.error('> Error!', command);
|
||||
console.error('> Error:', command);
|
||||
}
|
||||
|
||||
function debug(str) {
|
||||
|
||||
@@ -7,7 +7,7 @@ try {
|
||||
process.cwd();
|
||||
} catch (err: unknown) {
|
||||
if (isError(err) && err.message.includes('uv_cwd')) {
|
||||
console.error('Error! The current working directory does not exist.');
|
||||
console.error('Error: The current working directory does not exist.');
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import bytes from 'bytes';
|
||||
import Progress from 'progress';
|
||||
import chalk from 'chalk';
|
||||
import {
|
||||
ArchiveFormat,
|
||||
@@ -8,6 +7,7 @@ import {
|
||||
VercelClientOptions,
|
||||
} from '@vercel/client';
|
||||
import { Output } from '../output';
|
||||
import { progress } from '../output/progress';
|
||||
import Now from '../../util';
|
||||
import { Org } from '../../types';
|
||||
import ua from '../ua';
|
||||
@@ -68,7 +68,6 @@ export default async function processDeployment({
|
||||
} = args;
|
||||
|
||||
const { debug } = output;
|
||||
let bar: Progress | null = null;
|
||||
|
||||
const { env = {} } = requestBody;
|
||||
|
||||
@@ -114,32 +113,28 @@ export default async function processDeployment({
|
||||
const missingSize = missing
|
||||
.map((sha: string) => total.get(sha).data.length)
|
||||
.reduce((a: number, b: number) => a + b, 0);
|
||||
|
||||
output.stopSpinner();
|
||||
bar = new Progress(`${chalk.gray('>')} Upload [:bar] :percent :etas`, {
|
||||
width: 20,
|
||||
complete: '=',
|
||||
incomplete: '',
|
||||
total: missingSize,
|
||||
clear: true,
|
||||
});
|
||||
|
||||
bar.tick(0);
|
||||
const totalSizeHuman = bytes.format(missingSize, { decimalPlaces: 1 });
|
||||
|
||||
uploads.forEach((e: any) =>
|
||||
e.on('progress', () => {
|
||||
if (!bar) return;
|
||||
|
||||
const totalBytesUploaded = uploads.reduce((acc: number, e: any) => {
|
||||
const uploadedBytes = uploads.reduce((acc: number, e: any) => {
|
||||
return acc + e.bytesUploaded;
|
||||
}, 0);
|
||||
// set the current progress bar value
|
||||
bar.curr = totalBytesUploaded;
|
||||
// trigger rendering
|
||||
bar.tick(0);
|
||||
|
||||
if (bar.complete) {
|
||||
const bar = progress(uploadedBytes, missingSize);
|
||||
if (!bar || uploadedBytes === missingSize) {
|
||||
output.spinner(deployingSpinnerVal, 0);
|
||||
} else {
|
||||
const uploadedHuman = bytes.format(uploadedBytes, {
|
||||
decimalPlaces: 1,
|
||||
fixedDecimals: true,
|
||||
});
|
||||
output.spinner(
|
||||
`Uploading ${chalk.reset(
|
||||
`[${bar}] (${uploadedHuman}/${totalSizeHuman})`
|
||||
)}`,
|
||||
0
|
||||
);
|
||||
}
|
||||
})
|
||||
);
|
||||
@@ -154,10 +149,6 @@ export default async function processDeployment({
|
||||
}
|
||||
|
||||
if (event.type === 'created') {
|
||||
if (bar && !bar.complete) {
|
||||
bar.tick(bar.total + 1);
|
||||
}
|
||||
|
||||
await linkFolderToProject(
|
||||
output,
|
||||
cwd || paths[0],
|
||||
|
||||
@@ -73,7 +73,7 @@ export class Output {
|
||||
link?: string,
|
||||
action = 'Learn More'
|
||||
) => {
|
||||
this.print(`${chalk.red(`Error!`)} ${str}\n`);
|
||||
this.print(`${chalk.red(`Error:`)} ${str}\n`);
|
||||
const details = slug ? `https://err.sh/vercel/${slug}` : link;
|
||||
if (details) {
|
||||
this.print(`${chalk.bold(action)}: ${renderLink(details)}\n`);
|
||||
|
||||
@@ -23,5 +23,5 @@ export default function error(
|
||||
metric.exception(messages.join('\n')).send();
|
||||
}
|
||||
|
||||
return `${chalk.red('Error!')} ${messages.join('\n')}`;
|
||||
return `${chalk.red('Error:')} ${messages.join('\n')}`;
|
||||
}
|
||||
|
||||
23
packages/cli/src/util/output/progress.ts
Normal file
23
packages/cli/src/util/output/progress.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
export interface ProgressOptions {
|
||||
width?: number;
|
||||
complete?: string;
|
||||
incomplete?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a raw progress bar string.
|
||||
*/
|
||||
export function progress(
|
||||
current: number,
|
||||
total: number,
|
||||
opts: ProgressOptions = {}
|
||||
): string | null {
|
||||
const { width = 20, complete = '=', incomplete = '-' } = opts;
|
||||
if (total <= 0 || current < 0 || current > total) {
|
||||
// Let the caller decide how to handle out-of-range values
|
||||
return null;
|
||||
}
|
||||
const unit = total / width;
|
||||
const pos = Math.floor(current / unit);
|
||||
return `${complete.repeat(pos)}${incomplete.repeat(width - pos)}`;
|
||||
}
|
||||
@@ -22,28 +22,28 @@ export async function validateRootDirectory(
|
||||
const suffix = errorSuffix ? ` ${errorSuffix}` : '';
|
||||
|
||||
if (!pathStat) {
|
||||
output.print(
|
||||
`${chalk.red('Error!')} The provided path ${chalk.cyan(
|
||||
output.error(
|
||||
`The provided path ${chalk.cyan(
|
||||
`“${toHumanPath(path)}”`
|
||||
)} does not exist.${suffix}\n`
|
||||
)} does not exist.${suffix}`
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!pathStat.isDirectory()) {
|
||||
output.print(
|
||||
`${chalk.red('Error!')} The provided path ${chalk.cyan(
|
||||
output.error(
|
||||
`The provided path ${chalk.cyan(
|
||||
`“${toHumanPath(path)}”`
|
||||
)} is a file, but expected a directory.${suffix}\n`
|
||||
)} is a file, but expected a directory.${suffix}`
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!path.startsWith(cwd)) {
|
||||
output.print(
|
||||
`${chalk.red('Error!')} The provided path ${chalk.cyan(
|
||||
output.error(
|
||||
`The provided path ${chalk.cyan(
|
||||
`“${toHumanPath(path)}”`
|
||||
)} is outside of the project.${suffix}\n`
|
||||
)} is outside of the project.${suffix}`
|
||||
);
|
||||
return false;
|
||||
}
|
||||
@@ -59,7 +59,7 @@ export default async function validatePaths(
|
||||
|
||||
// can't deploy more than 1 path
|
||||
if (paths.length > 1) {
|
||||
output.print(`${chalk.red('Error!')} Can't deploy more than one path.\n`);
|
||||
output.error(`Can't deploy more than one path.`);
|
||||
return { valid: false, exitCode: 1 };
|
||||
}
|
||||
|
||||
@@ -69,11 +69,7 @@ export default async function validatePaths(
|
||||
const pathStat = await stat(path).catch(() => null);
|
||||
|
||||
if (!pathStat) {
|
||||
output.print(
|
||||
`${chalk.red('Error!')} Could not find ${chalk.cyan(
|
||||
`“${toHumanPath(path)}”`
|
||||
)}\n`
|
||||
);
|
||||
output.error(`Could not find ${chalk.cyan(`“${toHumanPath(path)}”`)}`);
|
||||
return { valid: false, exitCode: 1 };
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "nextjs",
|
||||
"name": "nextjs-node",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"dev": "next",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "nextjs",
|
||||
"name": "nextjs-src-dir",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"dev": "next",
|
||||
|
||||
@@ -445,11 +445,7 @@ test(
|
||||
test(
|
||||
'[vercel dev] Middleware that has no response',
|
||||
testFixtureStdio('middleware-no-response', async (testPath: any) => {
|
||||
await testPath(
|
||||
500,
|
||||
'/api/hello',
|
||||
'A server error has occurred\n\nEDGE_FUNCTION_INVOCATION_FAILED'
|
||||
);
|
||||
await testPath(200, '/api/hello', 'hello from a serverless function');
|
||||
})
|
||||
);
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ const {
|
||||
|
||||
jest.setTimeout(6 * 60 * 1000);
|
||||
|
||||
const isCI = !!process.env.CI;
|
||||
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
|
||||
const isCanary = () => getDistTag(cliVersion) === 'canary';
|
||||
|
||||
@@ -52,7 +53,7 @@ function fetchWithRetry(url, opts = {}) {
|
||||
return res;
|
||||
},
|
||||
{
|
||||
retries: opts.retries || 3,
|
||||
retries: opts.retries ?? 3,
|
||||
factor: 1,
|
||||
}
|
||||
);
|
||||
@@ -150,9 +151,9 @@ async function testPath(
|
||||
fetchOpts = {}
|
||||
) {
|
||||
const opts = {
|
||||
retries: isCI ? 5 : 0,
|
||||
...fetchOpts,
|
||||
redirect: 'manual-dont-change',
|
||||
retries: 5,
|
||||
status,
|
||||
};
|
||||
const url = `${origin}${path}`;
|
||||
@@ -330,7 +331,7 @@ function testFixtureStdio(
|
||||
Authorization: `Bearer ${token}`,
|
||||
},
|
||||
body: JSON.stringify(projectSettings),
|
||||
retries: 3,
|
||||
retries: isCI ? 3 : 0,
|
||||
status: 200,
|
||||
}
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "only-module",
|
||||
"name": "prefer-browser",
|
||||
"private": true,
|
||||
"main": "dist-main.js",
|
||||
"module": "dist-module.js",
|
||||
|
||||
34
packages/cli/test/integration.js
vendored
34
packages/cli/test/integration.js
vendored
@@ -360,7 +360,7 @@ test('default command should prompt login with empty auth.json', async t => {
|
||||
} catch (err) {
|
||||
t.true(
|
||||
err.stderr.includes(
|
||||
'Error! No existing credentials found. Please run `vercel login` or pass "--token"'
|
||||
'Error: No existing credentials found. Please run `vercel login` or pass "--token"'
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -749,7 +749,7 @@ test('deploy fails using --local-config flag with non-existent path', async t =>
|
||||
|
||||
t.is(exitCode, 1, formatOutput({ stderr, stdout }));
|
||||
|
||||
t.regex(stderr, /Error! Couldn't find a project configuration file at/);
|
||||
t.regex(stderr, /Error: Couldn't find a project configuration file at/);
|
||||
t.regex(stderr, /does-not-exist\.json/);
|
||||
});
|
||||
|
||||
@@ -1451,7 +1451,7 @@ test('login with unregistered user', async t => {
|
||||
console.log(stdout);
|
||||
console.log(exitCode);
|
||||
|
||||
const goal = `Error! Please sign up: https://vercel.com/signup`;
|
||||
const goal = `Error: Please sign up: https://vercel.com/signup`;
|
||||
const lines = stderr.trim().split('\n');
|
||||
const last = lines[lines.length - 1];
|
||||
|
||||
@@ -1629,7 +1629,7 @@ test('try to purchase a domain', async t => {
|
||||
t.is(exitCode, 1);
|
||||
t.regex(
|
||||
stderr,
|
||||
/Error! Could not purchase domain\. Please add a payment method using/
|
||||
/Error: Could not purchase domain\. Please add a payment method using/
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1655,7 +1655,7 @@ test('try to transfer-in a domain with "--code" option', async t => {
|
||||
|
||||
t.true(
|
||||
stderr.includes(
|
||||
`Error! The domain "${session}-test.com" is not transferable.`
|
||||
`Error: The domain "${session}-test.com" is not transferable.`
|
||||
)
|
||||
);
|
||||
t.is(exitCode, 1);
|
||||
@@ -1680,7 +1680,7 @@ test('try to move an invalid domain', async t => {
|
||||
console.log(stdout);
|
||||
console.log(exitCode);
|
||||
|
||||
t.true(stderr.includes(`Error! Domain not found under `));
|
||||
t.true(stderr.includes(`Error: Domain not found under `));
|
||||
t.is(exitCode, 1);
|
||||
});
|
||||
|
||||
@@ -1964,7 +1964,7 @@ test('try to create a builds deployments with wrong now.json', async t => {
|
||||
t.is(exitCode, 1);
|
||||
t.true(
|
||||
stderr.includes(
|
||||
'Error! Invalid now.json - should NOT have additional property `builder`. Did you mean `builds`?'
|
||||
'Error: Invalid now.json - should NOT have additional property `builder`. Did you mean `builds`?'
|
||||
)
|
||||
);
|
||||
t.true(stderr.includes('https://vercel.com/docs/configuration'));
|
||||
@@ -1988,7 +1988,7 @@ test('try to create a builds deployments with wrong vercel.json', async t => {
|
||||
t.is(exitCode, 1);
|
||||
t.true(
|
||||
stderr.includes(
|
||||
'Error! Invalid vercel.json - should NOT have additional property `fake`. Please remove it.'
|
||||
'Error: Invalid vercel.json - should NOT have additional property `fake`. Please remove it.'
|
||||
)
|
||||
);
|
||||
t.true(stderr.includes('https://vercel.com/docs/configuration'));
|
||||
@@ -2009,7 +2009,7 @@ test('try to create a builds deployments with wrong `build.env` property', async
|
||||
t.is(exitCode, 1, formatOutput({ stdout, stderr }));
|
||||
t.true(
|
||||
stderr.includes(
|
||||
'Error! Invalid vercel.json - should NOT have additional property `build.env`. Did you mean `{ "build": { "env": {"name": "value"} } }`?'
|
||||
'Error: Invalid vercel.json - should NOT have additional property `build.env`. Did you mean `{ "build": { "env": {"name": "value"} } }`?'
|
||||
),
|
||||
formatOutput({ stdout, stderr })
|
||||
);
|
||||
@@ -2171,7 +2171,7 @@ test('use build-env', async t => {
|
||||
});
|
||||
|
||||
test('try to deploy non-existing path', async t => {
|
||||
const goal = `Error! The specified file or directory "${session}" does not exist.`;
|
||||
const goal = `Error: The specified file or directory "${session}" does not exist.`;
|
||||
|
||||
const { stderr, stdout, exitCode } = await execa(
|
||||
binaryPath,
|
||||
@@ -2191,7 +2191,7 @@ test('try to deploy non-existing path', async t => {
|
||||
|
||||
test('try to deploy with non-existing team', async t => {
|
||||
const target = fixture('static-deployment');
|
||||
const goal = `Error! The specified scope does not exist`;
|
||||
const goal = `Error: The specified scope does not exist`;
|
||||
|
||||
const { stderr, stdout, exitCode } = await execa(
|
||||
binaryPath,
|
||||
@@ -2274,7 +2274,7 @@ test('try to initialize example to existing directory', async t => {
|
||||
tmpDir = tmp.dirSync({ unsafeCleanup: true });
|
||||
const cwd = tmpDir.name;
|
||||
const goal =
|
||||
'Error! Destination path "angular" already exists and is not an empty directory. You may use `--force` or `-f` to override it.';
|
||||
'Error: Destination path "angular" already exists and is not an empty directory. You may use `--force` or `-f` to override it.';
|
||||
|
||||
await ensureDir(path.join(cwd, 'angular'));
|
||||
createFile(path.join(cwd, 'angular', '.gitignore'));
|
||||
@@ -2291,7 +2291,7 @@ test('try to initialize misspelled example (noce) in non-tty', async t => {
|
||||
tmpDir = tmp.dirSync({ unsafeCleanup: true });
|
||||
const cwd = tmpDir.name;
|
||||
const goal =
|
||||
'Error! No example found for noce, run `vercel init` to see the list of available examples.';
|
||||
'Error: No example found for noce, run `vercel init` to see the list of available examples.';
|
||||
|
||||
const { stdout, stderr, exitCode } = await execute(['init', 'noce'], { cwd });
|
||||
|
||||
@@ -2307,7 +2307,7 @@ test('try to initialize example "example-404"', async t => {
|
||||
tmpDir = tmp.dirSync({ unsafeCleanup: true });
|
||||
const cwd = tmpDir.name;
|
||||
const goal =
|
||||
'Error! No example found for example-404, run `vercel init` to see the list of available examples.';
|
||||
'Error: No example found for example-404, run `vercel init` to see the list of available examples.';
|
||||
|
||||
const { stdout, stderr, exitCode } = await execute(['init', 'example-404'], {
|
||||
cwd,
|
||||
@@ -2483,7 +2483,7 @@ test('`vercel rm` should fail with unexpected option', async t => {
|
||||
t.is(output.exitCode, 1, formatOutput(output));
|
||||
t.regex(
|
||||
output.stderr,
|
||||
/Error! unknown or unexpected option: --fake/gm,
|
||||
/Error: unknown or unexpected option: --fake/gm,
|
||||
formatOutput(output)
|
||||
);
|
||||
});
|
||||
@@ -2777,7 +2777,7 @@ test('invalid `--token`', async t => {
|
||||
t.is(output.exitCode, 1, formatOutput(output));
|
||||
t.true(
|
||||
output.stderr.includes(
|
||||
'Error! You defined "--token", but its contents are invalid. Must not contain: "\\n", ",", "."'
|
||||
'Error: You defined "--token", but its contents are invalid. Must not contain: "\\n", ",", "."'
|
||||
)
|
||||
);
|
||||
});
|
||||
@@ -3500,7 +3500,7 @@ test('reject deploying with invalid token', async t => {
|
||||
t.is(exitCode, 1, formatOutput({ stderr, stdout }));
|
||||
t.regex(
|
||||
stderr,
|
||||
/Error! Could not retrieve Project Settings\. To link your Project, remove the `\.vercel` directory and deploy again\./g
|
||||
/Error: Could not retrieve Project Settings\. To link your Project, remove the `\.vercel` directory and deploy again\./g
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -711,7 +711,7 @@ describe('build', () => {
|
||||
|
||||
// Error gets printed to the terminal
|
||||
await expect(client.stderr).toOutput(
|
||||
'Error! Function must contain at least one property.'
|
||||
'Error: Function must contain at least one property.'
|
||||
);
|
||||
|
||||
// `builds.json` contains top-level "error" property
|
||||
|
||||
@@ -12,7 +12,7 @@ describe('deploy', () => {
|
||||
client.setArgv('deploy', __filename);
|
||||
const exitCodePromise = deploy(client);
|
||||
await expect(client.stderr).toOutput(
|
||||
`Error! Support for single file deployments has been removed.\nLearn More: https://vercel.link/no-single-file-deployments\n`
|
||||
`Error: Support for single file deployments has been removed.\nLearn More: https://vercel.link/no-single-file-deployments\n`
|
||||
);
|
||||
await expect(exitCodePromise).resolves.toEqual(1);
|
||||
});
|
||||
@@ -21,7 +21,7 @@ describe('deploy', () => {
|
||||
client.setArgv('deploy', __filename, join(__dirname, 'inspect.test.ts'));
|
||||
const exitCodePromise = deploy(client);
|
||||
await expect(client.stderr).toOutput(
|
||||
`Error! Can't deploy more than one path.\n`
|
||||
`Error: Can't deploy more than one path.\n`
|
||||
);
|
||||
await expect(exitCodePromise).resolves.toEqual(1);
|
||||
});
|
||||
@@ -30,7 +30,7 @@ describe('deploy', () => {
|
||||
client.setArgv('deploy', 'does-not-exists');
|
||||
const exitCodePromise = deploy(client);
|
||||
await expect(client.stderr).toOutput(
|
||||
`Error! The specified file or directory "does-not-exists" does not exist.\n`
|
||||
`Error: The specified file or directory "does-not-exists" does not exist.\n`
|
||||
);
|
||||
await expect(exitCodePromise).resolves.toEqual(1);
|
||||
});
|
||||
@@ -41,7 +41,7 @@ describe('deploy', () => {
|
||||
client.setArgv('deploy', cwd, '--prebuilt');
|
||||
const exitCodePromise = deploy(client);
|
||||
await expect(client.stderr).toOutput(
|
||||
'> Prebuilt deployment cannot be created because `vercel build` failed with error:\n\nError! The build failed (top-level)\n'
|
||||
'> Prebuilt deployment cannot be created because `vercel build` failed with error:\n\nError: The build failed (top-level)\n'
|
||||
);
|
||||
await expect(exitCodePromise).resolves.toEqual(1);
|
||||
});
|
||||
@@ -52,7 +52,7 @@ describe('deploy', () => {
|
||||
client.setArgv('deploy', cwd, '--prebuilt');
|
||||
const exitCodePromise = deploy(client);
|
||||
await expect(client.stderr).toOutput(
|
||||
'> Prebuilt deployment cannot be created because `vercel build` failed with error:\n\nError! The build failed within a Builder\n'
|
||||
'> Prebuilt deployment cannot be created because `vercel build` failed with error:\n\nError: The build failed within a Builder\n'
|
||||
);
|
||||
await expect(exitCodePromise).resolves.toEqual(1);
|
||||
});
|
||||
@@ -61,7 +61,7 @@ describe('deploy', () => {
|
||||
client.setArgv('deploy', __dirname, '--prebuilt');
|
||||
const exitCodePromise = deploy(client);
|
||||
await expect(client.stderr).toOutput(
|
||||
'Error! The "--prebuilt" option was used, but no prebuilt output found in ".vercel/output". Run `vercel build` to generate a local build.\n'
|
||||
'Error: The "--prebuilt" option was used, but no prebuilt output found in ".vercel/output". Run `vercel build` to generate a local build.\n'
|
||||
);
|
||||
await expect(exitCodePromise).resolves.toEqual(1);
|
||||
});
|
||||
@@ -80,7 +80,7 @@ describe('deploy', () => {
|
||||
client.setArgv('deploy', cwd, '--prebuilt', '--prod');
|
||||
const exitCodePromise = deploy(client);
|
||||
await expect(client.stderr).toOutput(
|
||||
'Error! The "--prebuilt" option was used with the target environment "production",' +
|
||||
'Error: The "--prebuilt" option was used with the target environment "production",' +
|
||||
' but the prebuilt output found in ".vercel/output" was built with target environment "preview".' +
|
||||
' Please run `vercel --prebuilt`.\n' +
|
||||
'Learn More: https://vercel.link/prebuilt-environment-mismatch\n'
|
||||
@@ -102,7 +102,7 @@ describe('deploy', () => {
|
||||
client.setArgv('deploy', cwd, '--prebuilt');
|
||||
const exitCodePromise = deploy(client);
|
||||
await expect(client.stderr).toOutput(
|
||||
'Error! The "--prebuilt" option was used with the target environment "preview",' +
|
||||
'Error: The "--prebuilt" option was used with the target environment "preview",' +
|
||||
' but the prebuilt output found in ".vercel/output" was built with target environment "production".' +
|
||||
' Please run `vercel --prebuilt --prod`.\n' +
|
||||
'Learn More: https://vercel.link/prebuilt-environment-mismatch\n'
|
||||
@@ -118,7 +118,7 @@ describe('deploy', () => {
|
||||
};
|
||||
const exitCodePromise = deploy(client);
|
||||
await expect(client.stderr).toOutput(
|
||||
'Error! The value of the `version` property within vercel.json can only be `2`.\n'
|
||||
'Error: The value of the `version` property within vercel.json can only be `2`.\n'
|
||||
);
|
||||
await expect(exitCodePromise).resolves.toEqual(1);
|
||||
});
|
||||
@@ -132,7 +132,7 @@ describe('deploy', () => {
|
||||
};
|
||||
const exitCodePromise = deploy(client);
|
||||
await expect(client.stderr).toOutput(
|
||||
'Error! The `version` property inside your vercel.json file must be a number.\n'
|
||||
'Error: The `version` property inside your vercel.json file must be a number.\n'
|
||||
);
|
||||
await expect(exitCodePromise).resolves.toEqual(1);
|
||||
});
|
||||
|
||||
@@ -80,7 +80,7 @@ describe('git', () => {
|
||||
const exitCode = await git(client);
|
||||
expect(exitCode).toEqual(1);
|
||||
await expect(client.stderr).toOutput(
|
||||
`Error! No local Git repository found. Run \`git clone <url>\` to clone a remote Git repository first.\n`
|
||||
`Error: No local Git repository found. Run \`git clone <url>\` to clone a remote Git repository first.\n`
|
||||
);
|
||||
} finally {
|
||||
process.chdir(originalCwd);
|
||||
@@ -102,7 +102,7 @@ describe('git', () => {
|
||||
const exitCode = await git(client);
|
||||
expect(exitCode).toEqual(1);
|
||||
await expect(client.stderr).toOutput(
|
||||
`Error! No remote URLs found in your Git config. Make sure you've configured a remote repo in your local Git config. Run \`git remote --help\` for more details.`
|
||||
`Error: No remote URLs found in your Git config. Make sure you've configured a remote repo in your local Git config. Run \`git remote --help\` for more details.`
|
||||
);
|
||||
} finally {
|
||||
await fs.rename(join(cwd, '.git'), join(cwd, 'git'));
|
||||
@@ -129,7 +129,7 @@ describe('git', () => {
|
||||
`Connecting Git remote: bababooey`
|
||||
);
|
||||
await expect(client.stderr).toOutput(
|
||||
`Error! Failed to parse Git repo data from the following remote URL: bababooey\n`
|
||||
`Error: Failed to parse Git repo data from the following remote URL: bababooey\n`
|
||||
);
|
||||
} finally {
|
||||
await fs.rename(join(cwd, '.git'), join(cwd, 'git'));
|
||||
|
||||
@@ -33,7 +33,7 @@ describe('inspect', () => {
|
||||
const exitCode = await inspect(client);
|
||||
expect(exitCode).toEqual(1);
|
||||
await expect(client.stderr).toOutput(
|
||||
`Error! Failed to find deployment "bad.com" in ${user.username}\n`
|
||||
`Error: Failed to find deployment "bad.com" in ${user.username}\n`
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -7,7 +7,7 @@ describe('login', () => {
|
||||
client.setArgv('login', '--token', 'foo');
|
||||
const exitCodePromise = login(client);
|
||||
await expect(client.stderr).toOutput(
|
||||
'Error! `--token` may not be used with the "login" command\n'
|
||||
'Error: `--token` may not be used with the "login" command\n'
|
||||
);
|
||||
await expect(exitCodePromise).resolves.toEqual(2);
|
||||
});
|
||||
|
||||
31
packages/cli/test/unit/util/output/progress.test.ts
Normal file
31
packages/cli/test/unit/util/output/progress.test.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { progress } from '../../../../src/util/output/progress';
|
||||
|
||||
describe('progress()', () => {
|
||||
test.each([
|
||||
{ current: 0, total: 5, opts: { width: 5 }, expected: '-----' },
|
||||
{ current: 1, total: 5, opts: { width: 5 }, expected: '=----' },
|
||||
{ current: 2, total: 5, opts: { width: 5 }, expected: '==---' },
|
||||
{ current: 3, total: 5, opts: { width: 5 }, expected: '===--' },
|
||||
{ current: 4, total: 5, opts: { width: 5 }, expected: '====-' },
|
||||
{ current: 5, total: 5, opts: { width: 5 }, expected: '=====' },
|
||||
{ current: 0, total: 12, expected: '--------------------' },
|
||||
{ current: 1, total: 12, expected: '=-------------------' },
|
||||
{ current: 2, total: 12, expected: '===-----------------' },
|
||||
{ current: 600, total: 1200, expected: '==========----------' },
|
||||
{
|
||||
current: 9,
|
||||
total: 10,
|
||||
opts: { complete: '.', incomplete: ' ', width: 10 },
|
||||
expected: '......... ',
|
||||
},
|
||||
{ current: 10, total: 10, expected: '====================' },
|
||||
{ current: 11, total: 10, expected: null },
|
||||
{ current: -1, total: 10, expected: null },
|
||||
{ current: 1, total: 0, expected: null },
|
||||
])(
|
||||
'$current / $total -> "$expected"',
|
||||
({ current, total, opts, expected }) => {
|
||||
expect(progress(current, total, opts)).toEqual(expected);
|
||||
}
|
||||
);
|
||||
});
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/client",
|
||||
"version": "12.2.2",
|
||||
"version": "12.2.4",
|
||||
"main": "dist/index.js",
|
||||
"typings": "dist/index.d.ts",
|
||||
"homepage": "https://vercel.com",
|
||||
@@ -31,7 +31,7 @@
|
||||
"@types/node": "12.0.4",
|
||||
"@types/node-fetch": "2.5.4",
|
||||
"@types/recursive-readdir": "2.2.0",
|
||||
"@types/tar-fs": "^2.0.1",
|
||||
"@types/tar-fs": "1.16.1",
|
||||
"typescript": "4.3.4"
|
||||
},
|
||||
"jest": {
|
||||
@@ -43,7 +43,7 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/build-utils": "5.4.0",
|
||||
"@vercel/build-utils": "5.4.2",
|
||||
"@vercel/routing-utils": "2.0.2",
|
||||
"@zeit/fetch": "5.2.0",
|
||||
"async-retry": "1.2.3",
|
||||
@@ -54,6 +54,7 @@
|
||||
"ms": "2.1.2",
|
||||
"node-fetch": "2.6.7",
|
||||
"querystring": "^0.2.0",
|
||||
"sleep-promise": "8.0.1"
|
||||
"sleep-promise": "8.0.1",
|
||||
"tar-fs": "1.16.3"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
# `@vercel/edge`
|
||||
|
||||
A set of utilities to help you deploy your app on the Edge using Vercel.
|
||||
A set of utilities to help you deploy any framework on the Edge using Vercel.
|
||||
Please [follow the documentation](./docs) for examples and usage.
|
||||
|
||||
262
packages/edge/docs/README.md
Normal file
262
packages/edge/docs/README.md
Normal file
@@ -0,0 +1,262 @@
|
||||
# @vercel/edge
|
||||
|
||||
## Table of contents
|
||||
|
||||
### Interfaces
|
||||
|
||||
- [ExtraResponseInit](interfaces/ExtraResponseInit.md)
|
||||
- [Geo](interfaces/Geo.md)
|
||||
|
||||
### Variables
|
||||
|
||||
- [CITY_HEADER_NAME](README.md#city_header_name)
|
||||
- [COUNTRY_HEADER_NAME](README.md#country_header_name)
|
||||
- [IP_HEADER_NAME](README.md#ip_header_name)
|
||||
- [LATITUDE_HEADER_NAME](README.md#latitude_header_name)
|
||||
- [LONGITUDE_HEADER_NAME](README.md#longitude_header_name)
|
||||
- [REGION_HEADER_NAME](README.md#region_header_name)
|
||||
|
||||
### Functions
|
||||
|
||||
- [geolocation](README.md#geolocation)
|
||||
- [ipAddress](README.md#ipaddress)
|
||||
- [next](README.md#next)
|
||||
- [rewrite](README.md#rewrite)
|
||||
|
||||
## Variables
|
||||
|
||||
### CITY_HEADER_NAME
|
||||
|
||||
• `Const` **CITY_HEADER_NAME**: `"x-vercel-ip-city"`
|
||||
|
||||
City of the original client IP as calculated by Vercel Proxy.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[src/edge-headers.ts:4](https://github.com/vercel/vercel/blob/main/packages/edge/src/edge-headers.ts#L4)
|
||||
|
||||
---
|
||||
|
||||
### COUNTRY_HEADER_NAME
|
||||
|
||||
• `Const` **COUNTRY_HEADER_NAME**: `"x-vercel-ip-country"`
|
||||
|
||||
Country of the original client IP as calculated by Vercel Proxy.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[src/edge-headers.ts:8](https://github.com/vercel/vercel/blob/main/packages/edge/src/edge-headers.ts#L8)
|
||||
|
||||
---
|
||||
|
||||
### IP_HEADER_NAME
|
||||
|
||||
• `Const` **IP_HEADER_NAME**: `"x-real-ip"`
|
||||
|
||||
Client IP as calcualted by Vercel Proxy.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[src/edge-headers.ts:12](https://github.com/vercel/vercel/blob/main/packages/edge/src/edge-headers.ts#L12)
|
||||
|
||||
---
|
||||
|
||||
### LATITUDE_HEADER_NAME
|
||||
|
||||
• `Const` **LATITUDE_HEADER_NAME**: `"x-vercel-ip-latitude"`
|
||||
|
||||
Latitude of the original client IP as calculated by Vercel Proxy.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[src/edge-headers.ts:16](https://github.com/vercel/vercel/blob/main/packages/edge/src/edge-headers.ts#L16)
|
||||
|
||||
---
|
||||
|
||||
### LONGITUDE_HEADER_NAME
|
||||
|
||||
• `Const` **LONGITUDE_HEADER_NAME**: `"x-vercel-ip-longitude"`
|
||||
|
||||
Longitude of the original client IP as calculated by Vercel Proxy.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[src/edge-headers.ts:20](https://github.com/vercel/vercel/blob/main/packages/edge/src/edge-headers.ts#L20)
|
||||
|
||||
---
|
||||
|
||||
### REGION_HEADER_NAME
|
||||
|
||||
• `Const` **REGION_HEADER_NAME**: `"x-vercel-ip-country-region"`
|
||||
|
||||
Region of the original client IP as calculated by Vercel Proxy.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[src/edge-headers.ts:24](https://github.com/vercel/vercel/blob/main/packages/edge/src/edge-headers.ts#L24)
|
||||
|
||||
## Functions
|
||||
|
||||
### geolocation
|
||||
|
||||
▸ **geolocation**(`request`): [`Geo`](interfaces/Geo.md)
|
||||
|
||||
Returns the location information for the incoming request.
|
||||
|
||||
**`See`**
|
||||
|
||||
- [CITY_HEADER_NAME](README.md#city_header_name)
|
||||
- [COUNTRY_HEADER_NAME](README.md#country_header_name)
|
||||
- [REGION_HEADER_NAME](README.md#region_header_name)
|
||||
- [LATITUDE_HEADER_NAME](README.md#latitude_header_name)
|
||||
- [LONGITUDE_HEADER_NAME](README.md#longitude_header_name)
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| :-------- | :-------- | :-------------------------------------------------------------- |
|
||||
| `request` | `Request` | The incoming request object which provides the geolocation data |
|
||||
|
||||
#### Returns
|
||||
|
||||
[`Geo`](interfaces/Geo.md)
|
||||
|
||||
#### Defined in
|
||||
|
||||
[src/edge-headers.ts:80](https://github.com/vercel/vercel/blob/main/packages/edge/src/edge-headers.ts#L80)
|
||||
|
||||
---
|
||||
|
||||
### ipAddress
|
||||
|
||||
▸ **ipAddress**(`request`): `string` \| `undefined`
|
||||
|
||||
Returns the IP address of the request from the headers.
|
||||
|
||||
**`See`**
|
||||
|
||||
[IP_HEADER_NAME](README.md#ip_header_name)
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| :-------- | :-------- | :------------------------------------------------ |
|
||||
| `request` | `Request` | The incoming request object which provides the IP |
|
||||
|
||||
#### Returns
|
||||
|
||||
`string` \| `undefined`
|
||||
|
||||
#### Defined in
|
||||
|
||||
[src/edge-headers.ts:66](https://github.com/vercel/vercel/blob/main/packages/edge/src/edge-headers.ts#L66)
|
||||
|
||||
---
|
||||
|
||||
### next
|
||||
|
||||
▸ **next**(`init?`): `Response`
|
||||
|
||||
Returns a Response that instructs the system to continue processing the request.
|
||||
|
||||
**`Example`**
|
||||
|
||||
<caption>No-op middleware</caption>
|
||||
|
||||
```ts
|
||||
import { next } from '@vercel/edge';
|
||||
|
||||
export default function middleware(_req: Request) {
|
||||
return next();
|
||||
}
|
||||
```
|
||||
|
||||
**`Example`**
|
||||
|
||||
<caption>Add response headers to all requests</caption>
|
||||
|
||||
```ts
|
||||
import { next } from '@vercel/edge';
|
||||
|
||||
export default function middleware(_req: Request) {
|
||||
return next({
|
||||
headers: { 'x-from-middleware': 'true' },
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------ | :----------------------------------------------------- | :---------------------------------- |
|
||||
| `init?` | [`ExtraResponseInit`](interfaces/ExtraResponseInit.md) | Additional options for the response |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Response`
|
||||
|
||||
#### Defined in
|
||||
|
||||
[src/middleware-helpers.ts:94](https://github.com/vercel/vercel/blob/main/packages/edge/src/middleware-helpers.ts#L94)
|
||||
|
||||
---
|
||||
|
||||
### rewrite
|
||||
|
||||
▸ **rewrite**(`destination`, `init?`): `Response`
|
||||
|
||||
Returns a response that rewrites the request to a different URL.
|
||||
|
||||
**`Example`**
|
||||
|
||||
<caption>Rewrite all feature-flagged requests from `/:path*` to `/experimental/:path*`</caption>
|
||||
|
||||
```ts
|
||||
import { rewrite, next } from '@vercel/edge';
|
||||
|
||||
export default async function middleware(req: Request) {
|
||||
const flagged = await getFlag(req, 'isExperimental');
|
||||
if (flagged) {
|
||||
const url = new URL(req.url);
|
||||
url.pathname = `/experimental{url.pathname}`;
|
||||
return rewrite(url);
|
||||
}
|
||||
|
||||
return next();
|
||||
}
|
||||
```
|
||||
|
||||
**`Example`**
|
||||
|
||||
<caption>JWT authentication for `/api/:path*` requests</caption>
|
||||
|
||||
```ts
|
||||
import { rewrite, next } from '@vercel/edge';
|
||||
|
||||
export default function middleware(req: Request) {
|
||||
const auth = checkJwt(req.headers.get('Authorization'));
|
||||
if (!checkJwt) {
|
||||
return rewrite(new URL('/api/error-unauthorized', req.url));
|
||||
}
|
||||
const url = new URL(req.url);
|
||||
url.searchParams.set('_userId', auth.userId);
|
||||
return rewrite(url);
|
||||
}
|
||||
|
||||
export const config = { matcher: '/api/users/:path*' };
|
||||
```
|
||||
|
||||
#### Parameters
|
||||
|
||||
| Name | Type | Description |
|
||||
| :------------ | :------------------------------------------------------------------------ | :---------------------------------- |
|
||||
| `destination` | `string` \| [`URL`](https://developer.mozilla.org/en-US/docs/Web/API/URL) | new URL to rewrite the request to |
|
||||
| `init?` | [`ExtraResponseInit`](interfaces/ExtraResponseInit.md) | Additional options for the response |
|
||||
|
||||
#### Returns
|
||||
|
||||
`Response`
|
||||
|
||||
#### Defined in
|
||||
|
||||
[src/middleware-helpers.ts:53](https://github.com/vercel/vercel/blob/main/packages/edge/src/middleware-helpers.ts#L53)
|
||||
56
packages/edge/docs/interfaces/ExtraResponseInit.md
Normal file
56
packages/edge/docs/interfaces/ExtraResponseInit.md
Normal file
@@ -0,0 +1,56 @@
|
||||
# Interface: ExtraResponseInit
|
||||
|
||||
## Hierarchy
|
||||
|
||||
- `Omit`<`ResponseInit`, `"headers"`\>
|
||||
|
||||
↳ **`ExtraResponseInit`**
|
||||
|
||||
## Table of contents
|
||||
|
||||
### Properties
|
||||
|
||||
- [headers](ExtraResponseInit.md#headers)
|
||||
- [status](ExtraResponseInit.md#status)
|
||||
- [statusText](ExtraResponseInit.md#statustext)
|
||||
|
||||
## Properties
|
||||
|
||||
### headers
|
||||
|
||||
• `Optional` **headers**: `HeadersInit`
|
||||
|
||||
These headers will be sent to the user response
|
||||
along with the response headers from the origin.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[src/middleware-helpers.ts:6](https://github.com/vercel/vercel/blob/main/packages/edge/src/middleware-helpers.ts#L6)
|
||||
|
||||
---
|
||||
|
||||
### status
|
||||
|
||||
• `Optional` **status**: `number`
|
||||
|
||||
#### Inherited from
|
||||
|
||||
Omit.status
|
||||
|
||||
#### Defined in
|
||||
|
||||
node_modules/typescript/lib/lib.dom.d.ts:1578
|
||||
|
||||
---
|
||||
|
||||
### statusText
|
||||
|
||||
• `Optional` **statusText**: `string`
|
||||
|
||||
#### Inherited from
|
||||
|
||||
Omit.statusText
|
||||
|
||||
#### Defined in
|
||||
|
||||
node_modules/typescript/lib/lib.dom.d.ts:1579
|
||||
73
packages/edge/docs/interfaces/Geo.md
Normal file
73
packages/edge/docs/interfaces/Geo.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# Interface: Geo
|
||||
|
||||
The location information of a given request.
|
||||
|
||||
## Table of contents
|
||||
|
||||
### Properties
|
||||
|
||||
- [city](Geo.md#city)
|
||||
- [country](Geo.md#country)
|
||||
- [latitude](Geo.md#latitude)
|
||||
- [longitude](Geo.md#longitude)
|
||||
- [region](Geo.md#region)
|
||||
|
||||
## Properties
|
||||
|
||||
### city
|
||||
|
||||
• `Optional` **city**: `string`
|
||||
|
||||
The city that the request originated from.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[src/edge-headers.ts:41](https://github.com/vercel/vercel/blob/main/packages/edge/src/edge-headers.ts#L41)
|
||||
|
||||
---
|
||||
|
||||
### country
|
||||
|
||||
• `Optional` **country**: `string`
|
||||
|
||||
The country that the request originated from.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[src/edge-headers.ts:44](https://github.com/vercel/vercel/blob/main/packages/edge/src/edge-headers.ts#L44)
|
||||
|
||||
---
|
||||
|
||||
### latitude
|
||||
|
||||
• `Optional` **latitude**: `string`
|
||||
|
||||
The latitude of the client.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[src/edge-headers.ts:50](https://github.com/vercel/vercel/blob/main/packages/edge/src/edge-headers.ts#L50)
|
||||
|
||||
---
|
||||
|
||||
### longitude
|
||||
|
||||
• `Optional` **longitude**: `string`
|
||||
|
||||
The longitude of the client.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[src/edge-headers.ts:53](https://github.com/vercel/vercel/blob/main/packages/edge/src/edge-headers.ts#L53)
|
||||
|
||||
---
|
||||
|
||||
### region
|
||||
|
||||
• `Optional` **region**: `string`
|
||||
|
||||
The [Vercel Edge Network region](https://vercel.com/docs/concepts/edge-network/regions) that received the request.
|
||||
|
||||
#### Defined in
|
||||
|
||||
[src/edge-headers.ts:47](https://github.com/vercel/vercel/blob/main/packages/edge/src/edge-headers.ts#L47)
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/edge",
|
||||
"version": "0.0.3",
|
||||
"version": "0.0.4",
|
||||
"license": "MIT",
|
||||
"main": "dist/index.js",
|
||||
"module": "dist/index.mjs",
|
||||
@@ -8,13 +8,17 @@
|
||||
"scripts": {
|
||||
"build": "tsup src/index.ts --dts --format esm,cjs",
|
||||
"test": "jest --env node --verbose --runInBand --bail",
|
||||
"test-unit": "yarn test"
|
||||
"test-unit": "yarn test",
|
||||
"build:docs": "typedoc && prettier --write docs/**/*.md docs/*.md"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@edge-runtime/jest-environment": "1.1.0-beta.7",
|
||||
"@types/jest": "27.4.1",
|
||||
"ts-node": "8.9.1",
|
||||
"tsup": "6.1.2",
|
||||
"typedoc": "0.23.10",
|
||||
"typedoc-plugin-markdown": "3.13.4",
|
||||
"typedoc-plugin-mdn-links": "2.0.0",
|
||||
"typescript": "4.7.4"
|
||||
},
|
||||
"jest": {
|
||||
|
||||
@@ -1,25 +1,25 @@
|
||||
/**
|
||||
* City of the original client IP calculated by Vercel Proxy.
|
||||
* City of the original client IP as calculated by Vercel Proxy.
|
||||
*/
|
||||
export const CITY_HEADER_NAME = 'x-vercel-ip-city';
|
||||
/**
|
||||
* Country of the original client IP calculated by Vercel Proxy.
|
||||
* Country of the original client IP as calculated by Vercel Proxy.
|
||||
*/
|
||||
export const COUNTRY_HEADER_NAME = 'x-vercel-ip-country';
|
||||
/**
|
||||
* Ip from Vercel Proxy. Do not confuse it with the client Ip.
|
||||
* Client IP as calcualted by Vercel Proxy.
|
||||
*/
|
||||
export const IP_HEADER_NAME = 'x-real-ip';
|
||||
/**
|
||||
* Latitude of the original client IP calculated by Vercel Proxy.
|
||||
* Latitude of the original client IP as calculated by Vercel Proxy.
|
||||
*/
|
||||
export const LATITUDE_HEADER_NAME = 'x-vercel-ip-latitude';
|
||||
/**
|
||||
* Longitude of the original client IP calculated by Vercel Proxy.
|
||||
* Longitude of the original client IP as calculated by Vercel Proxy.
|
||||
*/
|
||||
export const LONGITUDE_HEADER_NAME = 'x-vercel-ip-longitude';
|
||||
/**
|
||||
* Region of the original client IP calculated by Vercel Proxy.
|
||||
* Region of the original client IP as calculated by Vercel Proxy.
|
||||
*/
|
||||
export const REGION_HEADER_NAME = 'x-vercel-ip-country-region';
|
||||
|
||||
@@ -34,18 +34,22 @@ interface Request {
|
||||
}
|
||||
|
||||
/**
|
||||
* The location information of a given request
|
||||
* The location information of a given request.
|
||||
*/
|
||||
export interface Geo {
|
||||
/** The city that the request originated from */
|
||||
/** The city that the request originated from. */
|
||||
city?: string;
|
||||
/** The country that the request originated from */
|
||||
|
||||
/** The country that the request originated from. */
|
||||
country?: string;
|
||||
/** The Vercel Edge Network region that received the request */
|
||||
|
||||
/** The [Vercel Edge Network region](https://vercel.com/docs/concepts/edge-network/regions) that received the request. */
|
||||
region?: string;
|
||||
/** The latitude of the client */
|
||||
|
||||
/** The latitude of the client. */
|
||||
latitude?: string;
|
||||
/** The longitude of the client */
|
||||
|
||||
/** The longitude of the client. */
|
||||
longitude?: string;
|
||||
}
|
||||
|
||||
@@ -57,19 +61,21 @@ function getHeader(request: Request, key: string): string | undefined {
|
||||
* Returns the IP address of the request from the headers.
|
||||
*
|
||||
* @see {@link IP_HEADER_NAME}
|
||||
* @param request The incoming request object which provides the IP
|
||||
*/
|
||||
export function ipAddress(request: Request): string | undefined {
|
||||
return getHeader(request, IP_HEADER_NAME);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the location information from for the incoming request
|
||||
* Returns the location information for the incoming request.
|
||||
*
|
||||
* @see {@link CITY_HEADER_NAME}
|
||||
* @see {@link COUNTRY_HEADER_NAME}
|
||||
* @see {@link REGION_HEADER_NAME}
|
||||
* @see {@link LATITUDE_HEADER_NAME}
|
||||
* @see {@link LONGITUDE_HEADER_NAME}
|
||||
* @param request The incoming request object which provides the geolocation data
|
||||
*/
|
||||
export function geolocation(request: Request): Geo {
|
||||
return {
|
||||
|
||||
@@ -1,13 +1,54 @@
|
||||
export type ExtraResponseInit = Omit<ResponseInit, 'headers'> & {
|
||||
export interface ExtraResponseInit extends Omit<ResponseInit, 'headers'> {
|
||||
/**
|
||||
* These headers will be sent to the user response
|
||||
* along with the response headers from the origin
|
||||
* along with the response headers from the origin.
|
||||
*/
|
||||
headers?: HeadersInit;
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Rewrite the request into a different URL.
|
||||
* Returns a response that rewrites the request to a different URL.
|
||||
*
|
||||
* @param destination new URL to rewrite the request to
|
||||
* @param init Additional options for the response
|
||||
*
|
||||
*
|
||||
* @example
|
||||
* <caption>Rewrite all feature-flagged requests from `/:path*` to `/experimental/:path*`</caption>
|
||||
*
|
||||
* ```ts
|
||||
* import { rewrite, next } from '@vercel/edge';
|
||||
*
|
||||
* export default async function middleware(req: Request) {
|
||||
* const flagged = await getFlag(req, 'isExperimental');
|
||||
* if (flagged) {
|
||||
* const url = new URL(req.url);
|
||||
* url.pathname = `/experimental{url.pathname}`;
|
||||
* return rewrite(url);
|
||||
* }
|
||||
*
|
||||
* return next();
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* <caption>JWT authentication for `/api/:path*` requests</caption>
|
||||
*
|
||||
* ```ts
|
||||
* import { rewrite, next } from '@vercel/edge';
|
||||
*
|
||||
* export default function middleware(req: Request) {
|
||||
* const auth = checkJwt(req.headers.get('Authorization'));
|
||||
* if (!checkJwt) {
|
||||
* return rewrite(new URL('/api/error-unauthorized', req.url));
|
||||
* }
|
||||
* const url = new URL(req.url);
|
||||
* url.searchParams.set('_userId', auth.userId);
|
||||
* return rewrite(url);
|
||||
* }
|
||||
*
|
||||
* export const config = { matcher: '/api/users/:path*' };
|
||||
* ```
|
||||
*/
|
||||
export function rewrite(
|
||||
destination: string | URL,
|
||||
@@ -22,7 +63,33 @@ export function rewrite(
|
||||
}
|
||||
|
||||
/**
|
||||
* This tells the Middleware to continue with the request.
|
||||
* Returns a Response that instructs the system to continue processing the request.
|
||||
*
|
||||
* @param init Additional options for the response
|
||||
*
|
||||
* @example
|
||||
* <caption>No-op middleware</caption>
|
||||
*
|
||||
* ```ts
|
||||
* import { next } from '@vercel/edge';
|
||||
*
|
||||
* export default function middleware(_req: Request) {
|
||||
* return next();
|
||||
* }
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* <caption>Add response headers to all requests</caption>
|
||||
*
|
||||
* ```ts
|
||||
* import { next } from '@vercel/edge';
|
||||
*
|
||||
* export default function middleware(_req: Request) {
|
||||
* return next({
|
||||
* headers: { 'x-from-middleware': 'true' },
|
||||
* })
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export function next(init?: ExtraResponseInit): Response {
|
||||
const headers = new Headers(init?.headers ?? {});
|
||||
|
||||
38
packages/edge/test/docs.test.ts
vendored
Normal file
38
packages/edge/test/docs.test.ts
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
/// <reference types="@types/node" />
|
||||
|
||||
import { exec } from 'child_process';
|
||||
import { promisify } from 'util';
|
||||
import path from 'path';
|
||||
|
||||
const execAsync = promisify(exec);
|
||||
const test = process.platform === 'win32' ? it.skip : it;
|
||||
|
||||
test('docs are up to date', async () => {
|
||||
const cwd = path.resolve(__dirname, '../');
|
||||
await execAsync(`yarn build:docs`, { cwd });
|
||||
const result = await execAsync(`git status --short docs`, {
|
||||
cwd,
|
||||
encoding: 'utf-8',
|
||||
});
|
||||
|
||||
const lines = result.stdout
|
||||
.trim()
|
||||
.split(/(?:\r?\n)+/)
|
||||
.map(x => x.trim().split(/\s+/).slice(1).join(' '))
|
||||
.filter(x => x.startsWith('docs/'))
|
||||
.map(x => `* ${x}`)
|
||||
.join('\n')
|
||||
.trim();
|
||||
|
||||
if (lines !== '') {
|
||||
const diff = await execAsync(`git diff docs`, { cwd, encoding: 'utf8' });
|
||||
throw new Error(
|
||||
'Docs are not up to date. Please re-run `yarn build:docs` to re-generate them.\nChanges:\n' +
|
||||
lines +
|
||||
'\n\n' +
|
||||
diff.stdout
|
||||
);
|
||||
}
|
||||
|
||||
expect(result.stdout.trim()).toEqual('');
|
||||
}, 120000);
|
||||
10
packages/edge/typedoc.json
Normal file
10
packages/edge/typedoc.json
Normal file
@@ -0,0 +1,10 @@
|
||||
{
|
||||
"$schema": "https://typedoc.org/schema.json",
|
||||
"entryPoints": ["src/index.ts"],
|
||||
"plugin": ["typedoc-plugin-markdown", "typedoc-plugin-mdn-links"],
|
||||
"out": "docs",
|
||||
"githubPages": false,
|
||||
"gitRevision": "main",
|
||||
"readme": "none",
|
||||
"hideBreadcrumbs": true
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
<svg width="48" height="48" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M22.428.013c-.103.01-.431.042-.727.066C14.883.693 8.497 4.37 4.453 10.024A23.754 23.754 0 0 0 .216 20.51C.023 21.828 0 22.217 0 24.005c0 1.787.023 2.177.216 3.495 1.304 9.012 7.718 16.584 16.417 19.39 1.558.501 3.2.844 5.068 1.05.727.08 3.87.08 4.598 0 3.224-.356 5.954-1.154 8.648-2.529.412-.21.492-.267.436-.314-.038-.028-1.797-2.388-3.909-5.24l-3.838-5.184-4.809-7.117c-2.646-3.913-4.824-7.112-4.842-7.112-.019-.005-.038 3.157-.047 7.018-.014 6.76-.019 7.033-.103 7.192-.122.23-.216.324-.413.427-.15.075-.282.09-.99.09h-.812l-.216-.137a.878.878 0 0 1-.314-.342l-.099-.211.01-9.407.014-9.41.145-.184c.075-.098.235-.225.347-.286.193-.094.268-.103 1.08-.103.957 0 1.116.038 1.365.31.07.075 2.674 3.997 5.79 8.721s7.376 11.175 9.469 14.342l3.8 5.756.192-.127c1.704-1.107 3.505-2.683 4.932-4.325a23.888 23.888 0 0 0 5.65-12.268c.192-1.319.215-1.708.215-3.495 0-1.788-.023-2.177-.216-3.495-1.304-9.013-7.718-16.584-16.417-19.39C29.832.623 28.199.28 26.369.074c-.45-.047-3.551-.099-3.94-.061zm9.825 14.515a.947.947 0 0 1 .474.554c.038.122.047 2.73.038 8.608l-.014 8.436-1.488-2.28-1.492-2.28v-6.132c0-3.964.019-6.193.047-6.3a.957.957 0 0 1 .465-.592c.192-.098.262-.108 1-.108.694 0 .816.01.97.094z" fill="#fff"/></svg>
|
||||
<svg width="48" height="48" fill="none" xmlns="http://www.w3.org/2000/svg"><mask id="mask" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="48" height="48"><circle cx="24" cy="24" r="24" fill="#000"/></mask><g mask="url(#mask)"><circle cx="24" cy="24" r="23.2" fill="#000" stroke="#fff" stroke-width="1.6"/><path d="M39.8687 42.0055L18.4378 14.4H14.3999V33.592H17.6302V18.5023L37.333 43.9587C38.222 43.3637 39.069 42.7108 39.8687 42.0055Z" fill="url(#gradient0)"/><rect x="30.6667" y="14.4" width="3.2" height="19.2" fill="url(#gradient1)"/></g><defs><linearGradient id="gradient0" x1="29.0666" y1="31.0667" x2="38.5332" y2="42.8" gradientUnits="userSpaceOnUse"><stop stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></linearGradient><linearGradient id="gradient1" x1="32.2667" y1="14.4" x2="32.2132" y2="28.5001" gradientUnits="userSpaceOnUse"><stop stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></linearGradient></defs></svg>
|
||||
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 997 B |
@@ -1 +1 @@
|
||||
<svg width="48" height="48" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M22.428.013c-.103.01-.431.042-.727.066C14.883.693 8.497 4.37 4.453 10.024A23.754 23.754 0 0 0 .216 20.51C.023 21.828 0 22.217 0 24.005c0 1.787.023 2.177.216 3.495 1.304 9.012 7.718 16.584 16.417 19.39 1.558.501 3.2.844 5.068 1.05.727.08 3.87.08 4.598 0 3.224-.356 5.954-1.154 8.648-2.529.412-.21.492-.267.436-.314-.038-.028-1.797-2.388-3.909-5.24l-3.838-5.184-4.809-7.117c-2.646-3.913-4.824-7.112-4.842-7.112-.019-.005-.038 3.157-.047 7.018-.014 6.76-.019 7.033-.103 7.192-.122.23-.216.324-.413.427-.15.075-.282.09-.99.09h-.812l-.216-.137a.878.878 0 0 1-.314-.342l-.099-.211.01-9.407.014-9.41.145-.184c.075-.098.235-.225.347-.286.193-.094.268-.103 1.08-.103.957 0 1.116.038 1.365.31.07.075 2.674 3.997 5.79 8.721s7.376 11.175 9.469 14.342l3.8 5.756.192-.127c1.704-1.107 3.505-2.683 4.932-4.325a23.888 23.888 0 0 0 5.65-12.268c.192-1.319.215-1.708.215-3.495 0-1.788-.023-2.177-.216-3.495-1.304-9.013-7.718-16.584-16.417-19.39C29.832.623 28.199.28 26.369.074c-.45-.047-3.551-.099-3.94-.061zm9.825 14.515a.947.947 0 0 1 .474.554c.038.122.047 2.73.038 8.608l-.014 8.436-1.488-2.28-1.492-2.28v-6.132c0-3.964.019-6.193.047-6.3a.957.957 0 0 1 .465-.592c.192-.098.262-.108 1-.108.694 0 .816.01.97.094z" fill="#000"/></svg>
|
||||
<svg width="48" height="48" fill="none" xmlns="http://www.w3.org/2000/svg"><mask id="mask" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="48" height="48"><circle cx="24" cy="24" r="24" fill="#000"/></mask><g mask="url(#mask)"><circle cx="24" cy="24" r="23.2" fill="#000" stroke="#000" stroke-width="1.6"/><path d="M39.8687 42.0055L18.4378 14.4H14.3999V33.592H17.6302V18.5023L37.333 43.9587C38.222 43.3637 39.069 42.7108 39.8687 42.0055Z" fill="url(#gradient0)"/><rect x="30.6667" y="14.4" width="3.2" height="19.2" fill="url(#gradient1)"/></g><defs><linearGradient id="gradient0" x1="29.0666" y1="31.0667" x2="38.5332" y2="42.8" gradientUnits="userSpaceOnUse"><stop stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></linearGradient><linearGradient id="gradient1" x1="32.2667" y1="14.4" x2="32.2132" y2="28.5001" gradientUnits="userSpaceOnUse"><stop stop-color="#fff"/><stop offset="1" stop-color="#fff" stop-opacity="0"/></linearGradient></defs></svg>
|
||||
|
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 997 B |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/frameworks",
|
||||
"version": "1.1.3",
|
||||
"version": "1.1.4",
|
||||
"main": "./dist/frameworks.js",
|
||||
"types": "./dist/frameworks.d.ts",
|
||||
"files": [
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/fs-detectors",
|
||||
"version": "2.0.5",
|
||||
"version": "3.0.0",
|
||||
"description": "Vercel filesystem detectors",
|
||||
"main": "./dist/index.js",
|
||||
"types": "./dist/index.d.ts",
|
||||
@@ -19,7 +19,7 @@
|
||||
"test-unit": "yarn test"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/frameworks": "1.1.3",
|
||||
"@vercel/frameworks": "1.1.4",
|
||||
"@vercel/routing-utils": "2.0.2",
|
||||
"glob": "8.0.3",
|
||||
"js-yaml": "4.1.0",
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
import { posix as posixPath } from 'path';
|
||||
|
||||
export interface Stat {
|
||||
name: string;
|
||||
path: string;
|
||||
@@ -76,12 +78,43 @@ export abstract class DetectorFilesystem {
|
||||
|
||||
/**
|
||||
* Returns a list of Stat objects from the current working directory.
|
||||
* @param dirPath The path of the directory to read.
|
||||
* @param options.potentialFiles optional. Array of potential file names (relative to the path). If provided, these will be used to mark the filesystem caches as existing or not existing.
|
||||
*/
|
||||
public readdir = async (name: string): Promise<Stat[]> => {
|
||||
let p = this.readdirCache.get(name);
|
||||
public readdir = async (
|
||||
dirPath: string,
|
||||
options?: { potentialFiles?: string[] }
|
||||
): Promise<Stat[]> => {
|
||||
let p = this.readdirCache.get(dirPath);
|
||||
if (!p) {
|
||||
p = this._readdir(name);
|
||||
this.readdirCache.set(name, p);
|
||||
p = this._readdir(dirPath);
|
||||
this.readdirCache.set(dirPath, p);
|
||||
|
||||
const directoryContent = await p;
|
||||
const directoryFiles = new Set<string>();
|
||||
|
||||
for (const file of directoryContent) {
|
||||
if (file.type === 'file') {
|
||||
// we know this file exists, mark it as so on the filesystem
|
||||
this.fileCache.set(file.path, Promise.resolve(true));
|
||||
this.pathCache.set(file.path, Promise.resolve(true));
|
||||
directoryFiles.add(file.name);
|
||||
}
|
||||
}
|
||||
|
||||
if (options?.potentialFiles) {
|
||||
// calculate the set of paths that truly do not exist
|
||||
const filesThatDoNotExist = options.potentialFiles.filter(
|
||||
path => !directoryFiles.has(path)
|
||||
);
|
||||
for (const filePath of filesThatDoNotExist) {
|
||||
const fullFilePath =
|
||||
dirPath === '/' ? filePath : posixPath.join(dirPath, filePath);
|
||||
// we know this file does not exist, mark it as so on the filesystem
|
||||
this.fileCache.set(fullFilePath, Promise.resolve(false));
|
||||
this.pathCache.set(fullFilePath, Promise.resolve(false));
|
||||
}
|
||||
}
|
||||
}
|
||||
return p;
|
||||
};
|
||||
|
||||
@@ -59,6 +59,19 @@ export const workspaceManagers: Array<
|
||||
],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'default',
|
||||
slug: 'yarn',
|
||||
detectors: {
|
||||
every: [
|
||||
{
|
||||
path: 'package.json',
|
||||
matchContent:
|
||||
'"workspaces":\\s*(?:\\[[^\\]]*]|{[^}]*"packages":[^}]*})',
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export default workspaceManagers;
|
||||
|
||||
15
packages/fs-detectors/test/fixtures/38-workspaces-no-lock-file/a/package.json
vendored
Normal file
15
packages/fs-detectors/test/fixtures/38-workspaces-no-lock-file/a/package.json
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "a",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"debug": "^4.3.2"
|
||||
}
|
||||
}
|
||||
15
packages/fs-detectors/test/fixtures/38-workspaces-no-lock-file/b/package.json
vendored
Normal file
15
packages/fs-detectors/test/fixtures/38-workspaces-no-lock-file/b/package.json
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"name": "b",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"cowsay": "^1.5.0"
|
||||
}
|
||||
}
|
||||
8
packages/fs-detectors/test/fixtures/38-workspaces-no-lock-file/package.json
vendored
Normal file
8
packages/fs-detectors/test/fixtures/38-workspaces-no-lock-file/package.json
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"name": "21-npm-workspaces",
|
||||
"version": "1.0.0",
|
||||
"workspaces": [
|
||||
"a",
|
||||
"b"
|
||||
]
|
||||
}
|
||||
@@ -11,6 +11,7 @@ describe('workspace-managers', () => {
|
||||
['25-multiple-lock-files-yarn', 'yarn'],
|
||||
['26-multiple-lock-files-pnpm', 'pnpm'],
|
||||
['22-pnpm', null],
|
||||
['38-workspaces-no-lock-file', 'yarn'],
|
||||
])('with detectFramework', (fixturePath, frameworkSlug) => {
|
||||
const testName = frameworkSlug
|
||||
? `should detect a ${frameworkSlug} workspace for ${fixturePath}`
|
||||
|
||||
@@ -135,11 +135,18 @@ describe('DetectorFilesystem', () => {
|
||||
};
|
||||
|
||||
const fs = new VirtualFilesystem(files);
|
||||
const hasPathSpy = jest.spyOn(fs, '_hasPath');
|
||||
|
||||
expect(await fs.readdir('/')).toEqual([
|
||||
expect(await fs.readdir('/', { potentialFiles: ['config.rb'] })).toEqual([
|
||||
{ name: 'package.json', path: 'package.json', type: 'file' },
|
||||
{ name: 'packages', path: 'packages', type: 'dir' },
|
||||
]);
|
||||
expect(await fs.hasPath('package.json')).toBe(true);
|
||||
expect(hasPathSpy).not.toHaveBeenCalled();
|
||||
expect(await fs.hasPath('config.rb')).toBe(false);
|
||||
expect(hasPathSpy).not.toHaveBeenCalled();
|
||||
expect(await fs.hasPath('tsconfig.json')).toBe(false);
|
||||
expect(hasPathSpy).toHaveBeenCalled();
|
||||
|
||||
expect(await fs.readdir('packages')).toEqual([
|
||||
{ name: 'app1', path: 'packages/app1', type: 'dir' },
|
||||
@@ -151,13 +158,19 @@ describe('DetectorFilesystem', () => {
|
||||
{ name: 'app2', path: 'packages/app2', type: 'dir' },
|
||||
]);
|
||||
|
||||
expect(await fs.readdir('packages/app1')).toEqual([
|
||||
expect(
|
||||
await fs.readdir('packages/app1', { potentialFiles: ['package.json'] })
|
||||
).toEqual([
|
||||
{
|
||||
name: 'package.json',
|
||||
path: 'packages/app1/package.json',
|
||||
type: 'file',
|
||||
},
|
||||
]);
|
||||
|
||||
hasPathSpy.mock.calls.length = 0;
|
||||
expect(await fs.hasPath('packages/app1/package.json')).toBe(true);
|
||||
expect(hasPathSpy).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should be able to change directories', async () => {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/go",
|
||||
"version": "2.2.3",
|
||||
"version": "2.2.5",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/go",
|
||||
@@ -35,7 +35,7 @@
|
||||
"@types/jest": "28.1.6",
|
||||
"@types/node-fetch": "^2.3.0",
|
||||
"@types/tar": "^4.0.0",
|
||||
"@vercel/build-utils": "5.4.0",
|
||||
"@vercel/build-utils": "5.4.2",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"async-retry": "1.3.1",
|
||||
"execa": "^1.0.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/hydrogen",
|
||||
"version": "0.0.16",
|
||||
"version": "0.0.18",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index.js",
|
||||
"homepage": "https://vercel.com/docs",
|
||||
@@ -21,7 +21,7 @@
|
||||
"devDependencies": {
|
||||
"@types/jest": "27.5.1",
|
||||
"@types/node": "*",
|
||||
"@vercel/build-utils": "5.4.0",
|
||||
"@vercel/build-utils": "5.4.2",
|
||||
"typescript": "4.6.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/next",
|
||||
"version": "3.1.22",
|
||||
"version": "3.1.25",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/next-js",
|
||||
@@ -44,8 +44,8 @@
|
||||
"@types/semver": "6.0.0",
|
||||
"@types/text-table": "0.2.1",
|
||||
"@types/webpack-sources": "3.2.0",
|
||||
"@vercel/build-utils": "5.4.0",
|
||||
"@vercel/nft": "0.22.0",
|
||||
"@vercel/build-utils": "5.4.2",
|
||||
"@vercel/nft": "0.22.1",
|
||||
"@vercel/routing-utils": "2.0.2",
|
||||
"async-sema": "3.0.1",
|
||||
"buffer-crc32": "0.2.13",
|
||||
|
||||
@@ -2636,7 +2636,10 @@ async function getServerlessPages(params: {
|
||||
for (const [entry, normalizedEntry] of Object.entries(
|
||||
params.appPathRoutesManifest
|
||||
)) {
|
||||
const normalizedPath = `${path.join('.', normalizedEntry)}.js`;
|
||||
const normalizedPath = `${path.join(
|
||||
'.',
|
||||
normalizedEntry === '/' ? '/index' : normalizedEntry
|
||||
)}.js`;
|
||||
const globPath = `${path.join('.', entry)}.js`;
|
||||
|
||||
if (appPaths[globPath]) {
|
||||
|
||||
@@ -2352,7 +2352,22 @@ export async function getMiddlewareBundle({
|
||||
|
||||
for (const worker of workerConfigs.values()) {
|
||||
const edgeFile = worker.edgeFunction.name;
|
||||
const shortPath = edgeFile.replace(/^pages\//, '');
|
||||
let shortPath = edgeFile;
|
||||
|
||||
// Replacing the folder prefix for the page
|
||||
//
|
||||
// For `pages/`, use file base name directly:
|
||||
// pages/index -> index
|
||||
// For `app/`, use folder name, handle the root page as index:
|
||||
// app/route/page -> route
|
||||
// app/page -> index
|
||||
// app/index/page -> index/index
|
||||
if (shortPath.startsWith('pages/')) {
|
||||
shortPath = shortPath.replace(/^pages\//, '');
|
||||
} else if (shortPath.startsWith('app/') && shortPath.endsWith('/page')) {
|
||||
shortPath =
|
||||
shortPath.replace(/^app\//, '').replace(/(^|\/)page$/, '') || 'index';
|
||||
}
|
||||
|
||||
worker.edgeFunction.name = shortPath;
|
||||
source.edgeFunctions[shortPath] = worker.edgeFunction;
|
||||
|
||||
7
packages/next/test/fixtures/00-app-dir-edge/app/edge/page.server.js
vendored
Normal file
7
packages/next/test/fixtures/00-app-dir-edge/app/edge/page.server.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
export default function Page() {
|
||||
return <p>edge</p>;
|
||||
}
|
||||
|
||||
export const config = {
|
||||
runtime: 'experimental-edge',
|
||||
};
|
||||
7
packages/next/test/fixtures/00-app-dir-edge/app/index/page.server.js
vendored
Normal file
7
packages/next/test/fixtures/00-app-dir-edge/app/index/page.server.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
export default function page() {
|
||||
return 'index/page';
|
||||
}
|
||||
|
||||
export const config = {
|
||||
runtime: 'experimental-edge',
|
||||
};
|
||||
7
packages/next/test/fixtures/00-app-dir-edge/app/page.server.js
vendored
Normal file
7
packages/next/test/fixtures/00-app-dir-edge/app/page.server.js
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
export default function page() {
|
||||
return 'page';
|
||||
}
|
||||
|
||||
export const config = {
|
||||
runtime: 'experimental-edge',
|
||||
};
|
||||
9
packages/next/test/fixtures/00-app-dir-edge/next.config.js
vendored
Normal file
9
packages/next/test/fixtures/00-app-dir-edge/next.config.js
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
module.exports = {
|
||||
experimental: {
|
||||
appDir: true,
|
||||
runtime: 'experimental-edge',
|
||||
serverComponents: true,
|
||||
legacyBrowsers: false,
|
||||
browsersListForSwc: true,
|
||||
},
|
||||
};
|
||||
7
packages/next/test/fixtures/00-app-dir-edge/package.json
vendored
Normal file
7
packages/next/test/fixtures/00-app-dir-edge/package.json
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"next": "canary",
|
||||
"react": "experimental",
|
||||
"react-dom": "experimental"
|
||||
}
|
||||
}
|
||||
15
packages/next/test/fixtures/00-app-dir-edge/vercel.json
vendored
Normal file
15
packages/next/test/fixtures/00-app-dir-edge/vercel.json
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"builds": [
|
||||
{
|
||||
"src": "package.json",
|
||||
"use": "@vercel/next"
|
||||
}
|
||||
],
|
||||
"probes": [
|
||||
{
|
||||
"path": "/edge",
|
||||
"status": 200,
|
||||
"mustContain": "edge"
|
||||
}
|
||||
]
|
||||
}
|
||||
3
packages/next/test/fixtures/00-app-dir/app/page.server.js
vendored
Normal file
3
packages/next/test/fixtures/00-app-dir/app/page.server.js
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
export default function Page() {
|
||||
return <p>index app page</p>;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"dependencies": {
|
||||
"next": "https://files-26yo0dy1b-ijjk-testing.vercel.app",
|
||||
"next": "canary",
|
||||
"react": "experimental",
|
||||
"react-dom": "experimental"
|
||||
}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
import Link from 'next/link';
|
||||
export default function Page(props) {
|
||||
return (
|
||||
<>
|
||||
<p>hello from pages/index</p>
|
||||
<Link href="/dashboard">Dashboard</Link>
|
||||
</>
|
||||
);
|
||||
}
|
||||
@@ -24,7 +24,7 @@
|
||||
{
|
||||
"path": "/",
|
||||
"status": 200,
|
||||
"mustContain": "hello from pages/index"
|
||||
"mustContain": "index app page"
|
||||
},
|
||||
{
|
||||
"path": "/blog/123",
|
||||
|
||||
@@ -17,7 +17,6 @@ it('should build with app-dir correctly', async () => {
|
||||
for (const key of Object.keys(buildResult.output)) {
|
||||
if (buildResult.output[key].type === 'Lambda') {
|
||||
lambdas.add(buildResult.output[key]);
|
||||
console.log('found lambda', key);
|
||||
}
|
||||
}
|
||||
expect(lambdas.size).toBe(1);
|
||||
@@ -27,6 +26,26 @@ it('should build with app-dir correctly', async () => {
|
||||
expect(buildResult.output['dashboard/deployments/[id]']).toBeDefined();
|
||||
});
|
||||
|
||||
it('should build with app-dir in edg runtime correctly', async () => {
|
||||
const { buildResult } = await runBuildLambda(
|
||||
path.join(__dirname, '../fixtures/00-app-dir-edge')
|
||||
);
|
||||
|
||||
console.log('buildResult', buildResult);
|
||||
const edgeFunctions = new Set();
|
||||
|
||||
for (const key of Object.keys(buildResult.output)) {
|
||||
if (buildResult.output[key].type === 'EdgeFunction') {
|
||||
edgeFunctions.add(buildResult.output[key]);
|
||||
}
|
||||
}
|
||||
|
||||
expect(edgeFunctions.size).toBe(3);
|
||||
expect(buildResult.output['edge']).toBeDefined();
|
||||
expect(buildResult.output['index']).toBeDefined();
|
||||
expect(buildResult.output['index/index']).toBeDefined();
|
||||
});
|
||||
|
||||
it('should show error from basePath with legacy monorepo build', async () => {
|
||||
let error;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/node",
|
||||
"version": "2.5.11",
|
||||
"version": "2.5.14",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/node-js",
|
||||
@@ -29,12 +29,12 @@
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"@edge-runtime/vm": "1.1.0-beta.23",
|
||||
"@edge-runtime/vm": "1.1.0-beta.32",
|
||||
"@types/node": "*",
|
||||
"@vercel/build-utils": "5.4.0",
|
||||
"@vercel/build-utils": "5.4.2",
|
||||
"@vercel/node-bridge": "3.0.0",
|
||||
"@vercel/static-config": "2.0.3",
|
||||
"edge-runtime": "1.1.0-beta.23",
|
||||
"edge-runtime": "1.1.0-beta.32",
|
||||
"esbuild": "0.14.47",
|
||||
"exit-hook": "2.2.1",
|
||||
"node-fetch": "2.6.7",
|
||||
@@ -53,7 +53,7 @@
|
||||
"@types/node-fetch": "^2.6.1",
|
||||
"@types/test-listen": "1.1.0",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"@vercel/nft": "0.22.0",
|
||||
"@vercel/nft": "0.22.1",
|
||||
"content-type": "1.0.4",
|
||||
"cookie": "0.4.0",
|
||||
"etag": "1.8.1",
|
||||
|
||||
@@ -151,7 +151,8 @@ async function serializeRequest(message: IncomingMessage) {
|
||||
|
||||
async function compileUserCode(
|
||||
entrypointPath: string,
|
||||
entrypointLabel: string
|
||||
entrypointLabel: string,
|
||||
isMiddleware: boolean
|
||||
): Promise<undefined | { userCode: string; wasmAssets: WasmAssets }> {
|
||||
const { wasmAssets, plugin: edgeWasmPlugin } = createEdgeWasmPlugin();
|
||||
try {
|
||||
@@ -176,6 +177,8 @@ async function compileUserCode(
|
||||
const userCode = `
|
||||
${compiledFile.text};
|
||||
|
||||
const isMiddleware = ${isMiddleware};
|
||||
|
||||
addEventListener('fetch', async (event) => {
|
||||
try {
|
||||
let serializedRequest = await event.request.text();
|
||||
@@ -205,14 +208,26 @@ async function compileUserCode(
|
||||
let response = await edgeHandler(event.request, event);
|
||||
|
||||
if (!response) {
|
||||
throw new Error('Edge Function "${entrypointLabel}" did not return a response.');
|
||||
if (isMiddleware) {
|
||||
// allow empty responses to pass through
|
||||
response = new Response(null, {
|
||||
headers: {
|
||||
'x-middleware-next': '1',
|
||||
},
|
||||
});
|
||||
} else {
|
||||
throw new Error('Edge Function "${entrypointLabel}" did not return a response.');
|
||||
}
|
||||
}
|
||||
|
||||
return event.respondWith(response);
|
||||
} catch (error) {
|
||||
// we can't easily show a meaningful stack trace
|
||||
// so, stick to just the error message for now
|
||||
event.respondWith(new Response(error.message, {
|
||||
const msg = error.cause
|
||||
? (error.message + ': ' + (error.cause.message || error.cause))
|
||||
: error.message;
|
||||
event.respondWith(new Response(msg, {
|
||||
status: 500,
|
||||
headers: {
|
||||
'x-vercel-failed': 'edge-wrapper'
|
||||
@@ -277,9 +292,14 @@ async function createEdgeRuntime(params?: {
|
||||
|
||||
async function createEdgeEventHandler(
|
||||
entrypointPath: string,
|
||||
entrypointLabel: string
|
||||
entrypointLabel: string,
|
||||
isMiddleware: boolean
|
||||
): Promise<(request: IncomingMessage) => Promise<VercelProxyResponse>> {
|
||||
const userCode = await compileUserCode(entrypointPath, entrypointLabel);
|
||||
const userCode = await compileUserCode(
|
||||
entrypointPath,
|
||||
entrypointLabel,
|
||||
isMiddleware
|
||||
);
|
||||
const server = await createEdgeRuntime(userCode);
|
||||
|
||||
return async function (request: IncomingMessage) {
|
||||
@@ -349,7 +369,11 @@ async function createEventHandler(
|
||||
// an Edge Function, otherwise needs to be opted-in via
|
||||
// `export const config = { runtime: 'experimental-edge' }`
|
||||
if (config.middleware === true || runtime === 'experimental-edge') {
|
||||
return createEdgeEventHandler(entrypointPath, entrypoint);
|
||||
return createEdgeEventHandler(
|
||||
entrypointPath,
|
||||
entrypoint,
|
||||
config.middleware || false
|
||||
);
|
||||
}
|
||||
|
||||
return createServerlessEventHandler(entrypointPath, options);
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
import { readFileSync } from 'fs';
|
||||
import { join } from 'path';
|
||||
|
||||
export default function handler(_req, res) {
|
||||
// This build.js asset should be included but not the dep.js asset
|
||||
// because this is readFile(), not require(). It also shouldn't transpile
|
||||
// with babel because it should be considered an asset.
|
||||
const file = join(process.cwd(), 'assets', 'build.js');
|
||||
const content = readFileSync(file, 'utf8');
|
||||
res.setHeader('Content-Type', 'application/javascript');
|
||||
return res.end(content);
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
import dep from './dep.js';
|
||||
@@ -1,3 +0,0 @@
|
||||
// This file should not be included because the
|
||||
// api/index.js is performing a readFile(), not require().
|
||||
export const dep = 'dep1';
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"probes": [
|
||||
{
|
||||
"path": "/api",
|
||||
"mustContain": "import dep from './dep.js';"
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/python",
|
||||
"version": "3.1.12",
|
||||
"version": "3.1.14",
|
||||
"main": "./dist/index.js",
|
||||
"license": "MIT",
|
||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/python",
|
||||
@@ -22,7 +22,7 @@
|
||||
"devDependencies": {
|
||||
"@types/execa": "^0.9.0",
|
||||
"@types/jest": "27.4.1",
|
||||
"@vercel/build-utils": "5.4.0",
|
||||
"@vercel/build-utils": "5.4.2",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"execa": "^1.0.0",
|
||||
"typescript": "4.3.4"
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/redwood",
|
||||
"version": "1.0.20",
|
||||
"version": "1.0.23",
|
||||
"main": "./dist/index.js",
|
||||
"license": "MIT",
|
||||
"homepage": "https://vercel.com/docs",
|
||||
@@ -19,7 +19,7 @@
|
||||
"test-unit": "yarn test test/prepare-cache.test.js"
|
||||
},
|
||||
"dependencies": {
|
||||
"@vercel/nft": "0.22.0",
|
||||
"@vercel/nft": "0.22.1",
|
||||
"@vercel/routing-utils": "2.0.2",
|
||||
"semver": "6.1.1"
|
||||
},
|
||||
@@ -27,6 +27,6 @@
|
||||
"@types/aws-lambda": "8.10.19",
|
||||
"@types/node": "*",
|
||||
"@types/semver": "6.0.0",
|
||||
"@vercel/build-utils": "5.4.0"
|
||||
"@vercel/build-utils": "5.4.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/remix",
|
||||
"version": "1.0.21",
|
||||
"version": "1.0.24",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index.js",
|
||||
"homepage": "https://vercel.com/docs",
|
||||
@@ -20,12 +20,12 @@
|
||||
"default-server.js"
|
||||
],
|
||||
"dependencies": {
|
||||
"@vercel/nft": "0.22.0"
|
||||
"@vercel/nft": "0.22.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jest": "27.5.1",
|
||||
"@types/node": "*",
|
||||
"@vercel/build-utils": "5.4.0",
|
||||
"@vercel/build-utils": "5.4.2",
|
||||
"typescript": "4.6.4"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@vercel/ruby",
|
||||
"author": "Nathan Cahill <nathan@nathancahill.com>",
|
||||
"version": "1.3.29",
|
||||
"version": "1.3.31",
|
||||
"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": "5.4.0",
|
||||
"@vercel/build-utils": "5.4.2",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"execa": "2.0.4",
|
||||
"fs-extra": "^7.0.1",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vercel/static-build",
|
||||
"version": "1.0.20",
|
||||
"version": "1.0.22",
|
||||
"license": "MIT",
|
||||
"main": "./dist/index",
|
||||
"homepage": "https://vercel.com/docs/build-step",
|
||||
@@ -36,8 +36,8 @@
|
||||
"@types/ms": "0.7.31",
|
||||
"@types/node-fetch": "2.5.4",
|
||||
"@types/promise-timeout": "1.3.0",
|
||||
"@vercel/build-utils": "5.4.0",
|
||||
"@vercel/frameworks": "1.1.3",
|
||||
"@vercel/build-utils": "5.4.2",
|
||||
"@vercel/frameworks": "1.1.4",
|
||||
"@vercel/ncc": "0.24.0",
|
||||
"@vercel/routing-utils": "2.0.2",
|
||||
"fs-extra": "10.0.0",
|
||||
|
||||
133
yarn.lock
133
yarn.lock
@@ -719,10 +719,10 @@
|
||||
dependencies:
|
||||
"@jridgewell/trace-mapping" "0.3.9"
|
||||
|
||||
"@edge-runtime/format@^1.1.0-beta.23":
|
||||
version "1.1.0-beta.23"
|
||||
resolved "https://registry.yarnpkg.com/@edge-runtime/format/-/format-1.1.0-beta.23.tgz#c28fddee0c45a62be63f691a01306c611c99e739"
|
||||
integrity sha512-TuY7ywLzp2XQQZpM8cX1dzm2QMK2juvtpMVR8K61utL2qvokzJ4gBYLcPSKhH0EWAt4WwgymNVRX0cpdSLAqAg==
|
||||
"@edge-runtime/format@^1.1.0-beta.32":
|
||||
version "1.1.0-beta.32"
|
||||
resolved "https://registry.yarnpkg.com/@edge-runtime/format/-/format-1.1.0-beta.32.tgz#6f0d5a8726cc54ebb2b1dcb86fe25c0ff093731d"
|
||||
integrity sha512-wpQtbgHJuSF1fvDV6Gxg2L7uNpzhQnRl91DREgOdRfa3S8y9AANjPi1/g3GPBGPiGZoX2Fv+MKV6RgY5/jLfJA==
|
||||
|
||||
"@edge-runtime/jest-environment@1.1.0-beta.7":
|
||||
version "1.1.0-beta.7"
|
||||
@@ -736,22 +736,22 @@
|
||||
jest-mock "28.1.1"
|
||||
jest-util "28.1.1"
|
||||
|
||||
"@edge-runtime/primitives@^1.1.0-beta.23":
|
||||
version "1.1.0-beta.23"
|
||||
resolved "https://registry.yarnpkg.com/@edge-runtime/primitives/-/primitives-1.1.0-beta.23.tgz#b9b8d83e3dce63286cf80b8d5ece43f32420c4ab"
|
||||
integrity sha512-0vHcZZwyxjmw/so9irYtA82/+nAlJRs+1WpRYBx7iae1FOGCPM4BIKEmboWmwTuj7c6avz9kIbptokdMUPgV9A==
|
||||
"@edge-runtime/primitives@^1.1.0-beta.32":
|
||||
version "1.1.0-beta.33"
|
||||
resolved "https://registry.yarnpkg.com/@edge-runtime/primitives/-/primitives-1.1.0-beta.33.tgz#9bd0d866addfdc98ec32ff3ca0f6d24f412a5c03"
|
||||
integrity sha512-mAZw/YRhwkaPVYwSwOTJTMMzZxfuLze6VEepsrVO/4yjnxriOf2GREgLal6OBtTcEEC44q4lqS+OSd0QaSFZEQ==
|
||||
|
||||
"@edge-runtime/primitives@^1.1.0-beta.7":
|
||||
version "1.1.0-beta.7"
|
||||
resolved "https://registry.yarnpkg.com/@edge-runtime/primitives/-/primitives-1.1.0-beta.7.tgz#0450ee3e5e03a8898ee072c0d0ee01fd2c1ed8f1"
|
||||
integrity sha512-ZwuSMpmrf2mAj/O7EWxKOXrC03YMkU64N+CgvVFOtJGfhydk4Db/392Zama3BjNYAMOr/oY9L7HxfPutAFesKw==
|
||||
|
||||
"@edge-runtime/vm@1.1.0-beta.23", "@edge-runtime/vm@^1.1.0-beta.23":
|
||||
version "1.1.0-beta.23"
|
||||
resolved "https://registry.yarnpkg.com/@edge-runtime/vm/-/vm-1.1.0-beta.23.tgz#b55d9add18cb7bb57acf184f6cd7b6edec782a25"
|
||||
integrity sha512-XBp3rCuX4scJVOo2KconAotL5XGX3zdd8IkfDNr5VVSQ/B6HkiTNuf+EvzSQTpplF+fiyLTpfcP9EbNLibwLTA==
|
||||
"@edge-runtime/vm@1.1.0-beta.32", "@edge-runtime/vm@^1.1.0-beta.32":
|
||||
version "1.1.0-beta.32"
|
||||
resolved "https://registry.yarnpkg.com/@edge-runtime/vm/-/vm-1.1.0-beta.32.tgz#1bc9c77a88343478d50009f30813b9fbf8a0f4ad"
|
||||
integrity sha512-G0SH80am2XjlK6oFI3RoKlg1SBS5ZAeqakYasfNhJEXqM7g7tsoh5jURMQcNxpLvo48XBTgHgAVEMzhAGgDPZg==
|
||||
dependencies:
|
||||
"@edge-runtime/primitives" "^1.1.0-beta.23"
|
||||
"@edge-runtime/primitives" "^1.1.0-beta.32"
|
||||
|
||||
"@edge-runtime/vm@^1.1.0-beta.7":
|
||||
version "1.1.0-beta.7"
|
||||
@@ -2855,13 +2855,6 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.3.2.tgz#fc8c2825e4ed2142473b4a81064e6e081463d1b3"
|
||||
integrity sha512-eI5Yrz3Qv4KPUa/nSIAi0h+qX0XyewOliug5F2QAtuRg6Kjg6jfmxe1GIwoIRhZspD1A0RP8ANrPwvEXXtRFog==
|
||||
|
||||
"@types/progress@2.0.3":
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/progress/-/progress-2.0.3.tgz#7ccbd9c6d4d601319126c469e73b5bb90dfc8ccc"
|
||||
integrity sha512-bPOsfCZ4tsTlKiBjBhKnM8jpY5nmIll166IPD58D92hR7G7kZDfx5iB9wGF4NfZrdKolebjeAr3GouYkSGoJ/A==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/promise-timeout@1.3.0":
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/promise-timeout/-/promise-timeout-1.3.0.tgz#90649ff6f48c1ead9de142e6dd9f62f8c5a54022"
|
||||
@@ -2973,21 +2966,6 @@
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/tar-fs@^2.0.1":
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/tar-fs/-/tar-fs-2.0.1.tgz#6391dcad1b03dea2d79fac07371585ab54472bb1"
|
||||
integrity sha512-qlsQyIY9sN7p221xHuXKNoMfUenOcvEBN4zI8dGsYbYCqHtTarXOEXSIgUnK+GcR0fZDse6pAIc5pIrCh9NefQ==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
"@types/tar-stream" "*"
|
||||
|
||||
"@types/tar-stream@*":
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/@types/tar-stream/-/tar-stream-2.2.2.tgz#be9d0be9404166e4b114151f93e8442e6ab6fb1d"
|
||||
integrity sha512-1AX+Yt3icFuU6kxwmPakaiGrJUwG44MpuiqPg4dSolRFk6jmvs4b3IbUol9wKDLIgU76gevn3EwE8y/DkSJCZQ==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/tar@^4.0.0":
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@types/tar/-/tar-4.0.3.tgz#e2cce0b8ff4f285293243f5971bd7199176ac489"
|
||||
@@ -3234,10 +3212,10 @@
|
||||
resolved "https://registry.yarnpkg.com/@vercel/ncc/-/ncc-0.24.0.tgz#a2e8783a185caa99b5d8961a57dfc9665de16296"
|
||||
integrity sha512-crqItMcIwCkvdXY/V3/TzrHJQx6nbIaRqE1cOopJhgGX6izvNov40SmD//nS5flfEvdK54YGjwVVq+zG6crjOg==
|
||||
|
||||
"@vercel/nft@0.22.0":
|
||||
version "0.22.0"
|
||||
resolved "https://registry.yarnpkg.com/@vercel/nft/-/nft-0.22.0.tgz#586ed4edfd0dabc9bf07525044782198a0b31199"
|
||||
integrity sha512-hB80/093PPiCefN2gVbqv6J93MH+63Zr7uDCwkiS/U4W07DXkLoftbnkBmZoS0Q84LiTSl9DRVSHU4XYCX+sJA==
|
||||
"@vercel/nft@0.22.1":
|
||||
version "0.22.1"
|
||||
resolved "https://registry.yarnpkg.com/@vercel/nft/-/nft-0.22.1.tgz#0d91d2a21e3a7f0b23ce1550da9870eac4942828"
|
||||
integrity sha512-lYYZIoxRurqDOSoVIdBicGnpUIpfyaS5qVjdPq+EfI285WqtZK3NK/dyCkiyBul+X2U2OEhRyeMdXPCHGJbohw==
|
||||
dependencies:
|
||||
"@mapbox/node-pre-gyp" "^1.0.5"
|
||||
acorn "^8.6.0"
|
||||
@@ -5495,13 +5473,13 @@ ecc-jsbn@~0.1.1:
|
||||
jsbn "~0.1.0"
|
||||
safer-buffer "^2.1.0"
|
||||
|
||||
edge-runtime@1.1.0-beta.23:
|
||||
version "1.1.0-beta.23"
|
||||
resolved "https://registry.yarnpkg.com/edge-runtime/-/edge-runtime-1.1.0-beta.23.tgz#fd4d93f021c622e9b188399fa83e6bd5e445cb5e"
|
||||
integrity sha512-A7dO/Y+4UJnaxFcdz6pepL+0GcvvViWvf201oFQXepgdSxPDKiqxaayCag0eiirQ6OfF+cSTmPD3xrfEoAIjiQ==
|
||||
edge-runtime@1.1.0-beta.32:
|
||||
version "1.1.0-beta.32"
|
||||
resolved "https://registry.yarnpkg.com/edge-runtime/-/edge-runtime-1.1.0-beta.32.tgz#e43fd53c57fdba3c567b3fef50743cba00ff5e49"
|
||||
integrity sha512-fbqqUF3OKynqtWgExhjyxXX2SwbkWuwmjUYhml3Sv8Y/vkrTxyTKrxS0MoxUy5sGPB3BBEtpopn36cQgwlOpAg==
|
||||
dependencies:
|
||||
"@edge-runtime/format" "^1.1.0-beta.23"
|
||||
"@edge-runtime/vm" "^1.1.0-beta.23"
|
||||
"@edge-runtime/format" "^1.1.0-beta.32"
|
||||
"@edge-runtime/vm" "^1.1.0-beta.32"
|
||||
exit-hook "2.2.1"
|
||||
http-status "1.5.2"
|
||||
mri "1.2.0"
|
||||
@@ -6990,7 +6968,7 @@ graceful-fs@^4.2.9:
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.9.tgz#041b05df45755e587a24942279b9d113146e1c96"
|
||||
integrity sha512-NtNxqUcXgpW2iMrfqSfR73Glt39K+BLwWsPs94yR63v45T0Wbej7eRmL5cWfwEgqXnmjQp3zaJTshdRW/qC2ZQ==
|
||||
|
||||
handlebars@^4.7.6:
|
||||
handlebars@^4.7.6, handlebars@^4.7.7:
|
||||
version "4.7.7"
|
||||
resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.7.7.tgz#9ce33416aad02dbd6c8fafa8240d5d98004945a1"
|
||||
integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==
|
||||
@@ -8514,6 +8492,11 @@ json5@^2.2.1:
|
||||
resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c"
|
||||
integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==
|
||||
|
||||
jsonc-parser@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-3.1.0.tgz#73b8f0e5c940b83d03476bc2e51a20ef0932615d"
|
||||
integrity sha512-DRf0QjnNeCUds3xTjKlQQ3DpJD51GvDjJfnxUVWg6PZTo2otSm+slzNAxU/35hF8/oJIKoG9slq30JYOsF2azg==
|
||||
|
||||
jsonfile@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb"
|
||||
@@ -8955,6 +8938,11 @@ lru_map@0.3.3:
|
||||
resolved "https://registry.yarnpkg.com/lru_map/-/lru_map-0.3.3.tgz#b5c8351b9464cbd750335a79650a0ec0e56118dd"
|
||||
integrity sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0=
|
||||
|
||||
lunr@^2.3.9:
|
||||
version "2.3.9"
|
||||
resolved "https://registry.yarnpkg.com/lunr/-/lunr-2.3.9.tgz#18b123142832337dd6e964df1a5a7707b25d35e1"
|
||||
integrity sha512-zTU3DaZaF3Rt9rhN3uBMGQD3dD2/vFQqnvZCDv4dl5iOzq2IZQqTxu90r4E5J+nP70J3ilqVCrbho2eWaeW8Ow==
|
||||
|
||||
macos-release@^2.2.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/macos-release/-/macos-release-2.3.0.tgz#eb1930b036c0800adebccd5f17bc4c12de8bb71f"
|
||||
@@ -9045,6 +9033,11 @@ map-visit@^1.0.0:
|
||||
dependencies:
|
||||
object-visit "^1.0.0"
|
||||
|
||||
marked@^4.0.18:
|
||||
version "4.0.19"
|
||||
resolved "https://registry.yarnpkg.com/marked/-/marked-4.0.19.tgz#d36198d1ac1255525153c351c68c75bc1d7aee46"
|
||||
integrity sha512-rgQF/OxOiLcvgUAj1Q1tAf4Bgxn5h5JZTp04Fx4XUkVhs7B+7YA9JEWJhJpoO8eJt8MkZMwqLCNeNqj1bCREZQ==
|
||||
|
||||
matcher@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/matcher/-/matcher-2.1.0.tgz#64e1041c15b993e23b786f93320a7474bf833c28"
|
||||
@@ -9301,7 +9294,7 @@ minimatch@5.0.1:
|
||||
dependencies:
|
||||
brace-expansion "^2.0.1"
|
||||
|
||||
minimatch@^5.0.1:
|
||||
minimatch@^5.0.1, minimatch@^5.1.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-5.1.0.tgz#1717b464f4971b144f6aabe8f2d0b8e4511e09c7"
|
||||
integrity sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==
|
||||
@@ -10521,11 +10514,6 @@ process-nextick-args@~2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.1.tgz#7820d9b16120cc55ca9ae7792680ae7dba6d7fe2"
|
||||
integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==
|
||||
|
||||
progress@2.0.3:
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.3.tgz#7e8cf8d8f5b8f239c1bc68beb4eb78567d572ef8"
|
||||
integrity sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==
|
||||
|
||||
promise-inflight@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3"
|
||||
@@ -11368,6 +11356,15 @@ shebang-regex@^3.0.0:
|
||||
resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172"
|
||||
integrity sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==
|
||||
|
||||
shiki@^0.10.1:
|
||||
version "0.10.1"
|
||||
resolved "https://registry.yarnpkg.com/shiki/-/shiki-0.10.1.tgz#6f9a16205a823b56c072d0f1a0bcd0f2646bef14"
|
||||
integrity sha512-VsY7QJVzU51j5o1+DguUd+6vmCmZ5v/6gYu4vyYAhzjuNQU6P/vmSy4uQaOhvje031qQMiW0d2BwgMH52vqMng==
|
||||
dependencies:
|
||||
jsonc-parser "^3.0.0"
|
||||
vscode-oniguruma "^1.6.1"
|
||||
vscode-textmate "5.2.0"
|
||||
|
||||
signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3:
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
|
||||
@@ -12615,6 +12612,28 @@ typedarray@^0.0.6:
|
||||
resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777"
|
||||
integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=
|
||||
|
||||
typedoc-plugin-markdown@3.13.4:
|
||||
version "3.13.4"
|
||||
resolved "https://registry.yarnpkg.com/typedoc-plugin-markdown/-/typedoc-plugin-markdown-3.13.4.tgz#4c2f02b254c47d25b91579177900c1da5c5579b8"
|
||||
integrity sha512-E/EBBmu6ARtnbswZGtBVBB/BfukZiGMOlqPc0RXCI/NFitONBahFqbCAF5fKQlijlcfipJj5pw5AMFH3NytrAw==
|
||||
dependencies:
|
||||
handlebars "^4.7.7"
|
||||
|
||||
typedoc-plugin-mdn-links@2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/typedoc-plugin-mdn-links/-/typedoc-plugin-mdn-links-2.0.0.tgz#b43893bc7bdbb94927091f66d465f31e8440ad6c"
|
||||
integrity sha512-IGLuelXPOenGdmklr5DHgPPf/MfZj7aEYCxCMtPN8C1D0lA7w0YLahd0jhDDcOMU7zL1EPcM5pPnhZHltDhqGQ==
|
||||
|
||||
typedoc@0.23.10:
|
||||
version "0.23.10"
|
||||
resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.23.10.tgz#285d595a5f2e35ccdf6f38eba4dfe951d5bff461"
|
||||
integrity sha512-03EUiu/ZuScUBMnY6p0lY+HTH8SwhzvRE3gImoemdPDWXPXlks83UGTx++lyquWeB1MTwm9D9Ca8RIjkK3AFfQ==
|
||||
dependencies:
|
||||
lunr "^2.3.9"
|
||||
marked "^4.0.18"
|
||||
minimatch "^5.1.0"
|
||||
shiki "^0.10.1"
|
||||
|
||||
typescript@4.3.4:
|
||||
version "4.3.4"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.4.tgz#3f85b986945bcf31071decdd96cf8bfa65f9dcbc"
|
||||
@@ -12928,6 +12947,16 @@ verror@1.10.0:
|
||||
core-util-is "1.0.2"
|
||||
extsprintf "^1.2.0"
|
||||
|
||||
vscode-oniguruma@^1.6.1:
|
||||
version "1.6.2"
|
||||
resolved "https://registry.yarnpkg.com/vscode-oniguruma/-/vscode-oniguruma-1.6.2.tgz#aeb9771a2f1dbfc9083c8a7fdd9cccaa3f386607"
|
||||
integrity sha512-KH8+KKov5eS/9WhofZR8M8dMHWN2gTxjMsG4jd04YhpbPR91fUj7rYQ2/XjeHCJWbg7X++ApRIU9NUwM2vTvLA==
|
||||
|
||||
vscode-textmate@5.2.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/vscode-textmate/-/vscode-textmate-5.2.0.tgz#01f01760a391e8222fe4f33fbccbd1ad71aed74e"
|
||||
integrity sha512-Uw5ooOQxRASHgu6C7GVvUxisKXfSgW4oFlO+aa+PAkgmH89O3CXxEEzNRNtHSqtXFTl0nAC1uYj0GMSH27uwtQ==
|
||||
|
||||
walker@^1.0.7:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb"
|
||||
|
||||
Reference in New Issue
Block a user