mirror of
https://github.com/LukeHagar/vercel.git
synced 2025-12-11 21:07:47 +00:00
Compare commits
12 Commits
@vercel/py
...
@vercel/py
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
547e88228e | ||
|
|
9bfb5dd535 | ||
|
|
81ea84fae8 | ||
|
|
fa8bf07be4 | ||
|
|
cc9dce73ad | ||
|
|
bba7cbd411 | ||
|
|
9a3739bebd | ||
|
|
8c62de16ce | ||
|
|
e9333988d7 | ||
|
|
fb001ce7eb | ||
|
|
b399fe7037 | ||
|
|
88385b3c84 |
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vercel/build-utils",
|
"name": "@vercel/build-utils",
|
||||||
"version": "4.2.0",
|
"version": "4.2.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"types": "./dist/index.d.js",
|
"types": "./dist/index.d.js",
|
||||||
|
|||||||
@@ -61,6 +61,13 @@ export interface SpawnOptionsExtended extends SpawnOptions {
|
|||||||
* Pretty formatted command that is being spawned for logging purposes.
|
* Pretty formatted command that is being spawned for logging purposes.
|
||||||
*/
|
*/
|
||||||
prettyCommand?: string;
|
prettyCommand?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns instead of throwing an error when the process exits with a
|
||||||
|
* non-0 exit code. When relevant, the returned object will include
|
||||||
|
* the error code, stdout and stderr.
|
||||||
|
*/
|
||||||
|
ignoreNon0Exit?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function spawnAsync(
|
export function spawnAsync(
|
||||||
@@ -79,7 +86,7 @@ export function spawnAsync(
|
|||||||
|
|
||||||
child.on('error', reject);
|
child.on('error', reject);
|
||||||
child.on('close', (code, signal) => {
|
child.on('close', (code, signal) => {
|
||||||
if (code === 0) {
|
if (code === 0 || opts.ignoreNon0Exit) {
|
||||||
return resolve();
|
return resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -123,24 +130,24 @@ export function execAsync(
|
|||||||
|
|
||||||
child.on('error', reject);
|
child.on('error', reject);
|
||||||
child.on('close', (code, signal) => {
|
child.on('close', (code, signal) => {
|
||||||
if (code !== 0) {
|
if (code === 0 || opts.ignoreNon0Exit) {
|
||||||
const cmd = opts.prettyCommand
|
return resolve({
|
||||||
? `Command "${opts.prettyCommand}"`
|
code,
|
||||||
: 'Command';
|
stdout: Buffer.concat(stdoutList).toString(),
|
||||||
|
stderr: Buffer.concat(stderrList).toString(),
|
||||||
return reject(
|
});
|
||||||
new NowBuildError({
|
|
||||||
code: `BUILD_UTILS_EXEC_${code || signal}`,
|
|
||||||
message: `${cmd} exited with ${code || signal}`,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return resolve({
|
const cmd = opts.prettyCommand
|
||||||
code,
|
? `Command "${opts.prettyCommand}"`
|
||||||
stdout: Buffer.concat(stdoutList).toString(),
|
: 'Command';
|
||||||
stderr: Buffer.concat(stderrList).toString(),
|
|
||||||
});
|
return reject(
|
||||||
|
new NowBuildError({
|
||||||
|
code: `BUILD_UTILS_EXEC_${code || signal}`,
|
||||||
|
message: `${cmd} exited with ${code || signal}`,
|
||||||
|
})
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@@ -166,9 +173,30 @@ export async function execCommand(command: string, options: SpawnOptions = {}) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function getNodeBinPath({ cwd }: { cwd: string }) {
|
export async function getNodeBinPath({
|
||||||
const { stdout } = await execAsync('npm', ['bin'], { cwd });
|
cwd,
|
||||||
return stdout.trim();
|
}: {
|
||||||
|
cwd: string;
|
||||||
|
}): Promise<string | undefined> {
|
||||||
|
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})`,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
async function chmodPlusX(fsPath: string) {
|
async function chmodPlusX(fsPath: string) {
|
||||||
|
|||||||
29
packages/build-utils/test/unit.exec-async.test.ts
vendored
Normal file
29
packages/build-utils/test/unit.exec-async.test.ts
vendored
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import { execAsync, NowBuildError } from '../src';
|
||||||
|
|
||||||
|
it('should execute a command', async () => {
|
||||||
|
const { code, stdout, stderr } = await execAsync('echo', ['hello']);
|
||||||
|
|
||||||
|
expect(code).toBe(0);
|
||||||
|
expect(stdout).toContain('hello');
|
||||||
|
expect(stderr).toBe('');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw if the command exits with non-0 code', async () => {
|
||||||
|
await expect(execAsync('find', ['unknown-file'])).rejects.toBeInstanceOf(
|
||||||
|
NowBuildError
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return if the command exits with non-0 code and ignoreNon0Exit=true', async () => {
|
||||||
|
const { code, stdout, stderr } = await execAsync('find', ['unknown-file'], {
|
||||||
|
ignoreNon0Exit: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(code).toBe(process.platform === 'win32' ? 2 : 1);
|
||||||
|
expect(stdout).toBe('');
|
||||||
|
expect(stderr).toContain(
|
||||||
|
process.platform === 'win32'
|
||||||
|
? 'Parameter format not correct'
|
||||||
|
: 'No such file or directory'
|
||||||
|
);
|
||||||
|
});
|
||||||
21
packages/build-utils/test/unit.spawn-async.test.ts
vendored
Normal file
21
packages/build-utils/test/unit.spawn-async.test.ts
vendored
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
import { spawnAsync, NowBuildError } from '../src';
|
||||||
|
|
||||||
|
it('should execute a command', async () => {
|
||||||
|
// should resolve (it doesn't return anything, so it resolves with "undefined")
|
||||||
|
await expect(spawnAsync('echo', ['hello'])).resolves.toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw if the command exits with non-0 code', async () => {
|
||||||
|
await expect(spawnAsync('find', ['unknown-file'])).rejects.toBeInstanceOf(
|
||||||
|
NowBuildError
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should return if the command exits with non-0 code and ignoreNon0Exit=true', async () => {
|
||||||
|
// should resolve (it doesn't return anything, so it resolves with "undefined")
|
||||||
|
await expect(
|
||||||
|
spawnAsync('find', ['unknown-file'], {
|
||||||
|
ignoreNon0Exit: true,
|
||||||
|
})
|
||||||
|
).resolves.toBeUndefined();
|
||||||
|
});
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "vercel",
|
"name": "vercel",
|
||||||
"version": "25.2.0",
|
"version": "25.2.3",
|
||||||
"preferGlobal": true,
|
"preferGlobal": true,
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"description": "The command-line interface for Vercel",
|
"description": "The command-line interface for Vercel",
|
||||||
@@ -42,15 +42,15 @@
|
|||||||
"node": ">= 14"
|
"node": ">= 14"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vercel/build-utils": "4.2.0",
|
"@vercel/build-utils": "4.2.1",
|
||||||
"@vercel/go": "2.0.2",
|
"@vercel/go": "2.0.3",
|
||||||
"@vercel/next": "3.1.0",
|
"@vercel/next": "3.1.2",
|
||||||
"@vercel/node": "2.3.0",
|
"@vercel/node": "2.3.3",
|
||||||
"@vercel/python": "3.0.2",
|
"@vercel/python": "3.0.3",
|
||||||
"@vercel/redwood": "1.0.2",
|
"@vercel/redwood": "1.0.4",
|
||||||
"@vercel/remix": "1.0.2",
|
"@vercel/remix": "1.0.4",
|
||||||
"@vercel/ruby": "1.3.10",
|
"@vercel/ruby": "1.3.11",
|
||||||
"@vercel/static-build": "1.0.2",
|
"@vercel/static-build": "1.0.3",
|
||||||
"update-notifier": "5.1.0"
|
"update-notifier": "5.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -95,7 +95,7 @@
|
|||||||
"@types/which": "1.3.2",
|
"@types/which": "1.3.2",
|
||||||
"@types/write-json-file": "2.2.1",
|
"@types/write-json-file": "2.2.1",
|
||||||
"@types/yauzl-promise": "2.1.0",
|
"@types/yauzl-promise": "2.1.0",
|
||||||
"@vercel/client": "12.0.2",
|
"@vercel/client": "12.0.3",
|
||||||
"@vercel/frameworks": "1.0.2",
|
"@vercel/frameworks": "1.0.2",
|
||||||
"@vercel/ncc": "0.24.0",
|
"@vercel/ncc": "0.24.0",
|
||||||
"@zeit/fun": "0.11.2",
|
"@zeit/fun": "0.11.2",
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ import confirm from '../../util/input/confirm';
|
|||||||
import findAliasByAliasOrId from '../../util/alias/find-alias-by-alias-or-id';
|
import findAliasByAliasOrId from '../../util/alias/find-alias-by-alias-or-id';
|
||||||
|
|
||||||
import { Alias } from '../../types';
|
import { Alias } from '../../types';
|
||||||
import { Output } from '../../util/output';
|
|
||||||
import { isValidName } from '../../util/is-valid-name';
|
import { isValidName } from '../../util/is-valid-name';
|
||||||
import { getCommandName } from '../../util/pkg-name';
|
import { getCommandName } from '../../util/pkg-name';
|
||||||
|
|
||||||
@@ -71,7 +70,7 @@ export default async function rm(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const removeStamp = stamp();
|
const removeStamp = stamp();
|
||||||
if (!opts['--yes'] && !(await confirmAliasRemove(output, alias))) {
|
if (!opts['--yes'] && !(await confirmAliasRemove(client, alias))) {
|
||||||
output.log('Aborted');
|
output.log('Aborted');
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -85,7 +84,7 @@ export default async function rm(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function confirmAliasRemove(output: Output, alias: Alias) {
|
async function confirmAliasRemove(client: Client, alias: Alias) {
|
||||||
const srcUrl = alias.deployment
|
const srcUrl = alias.deployment
|
||||||
? chalk.underline(alias.deployment.url)
|
? chalk.underline(alias.deployment.url)
|
||||||
: null;
|
: null;
|
||||||
@@ -104,7 +103,7 @@ async function confirmAliasRemove(output: Output, alias: Alias) {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
output.log(`The following alias will be removed permanently`);
|
client.output.log(`The following alias will be removed permanently`);
|
||||||
output.print(` ${tbl}\n`);
|
client.output.print(` ${tbl}\n`);
|
||||||
return confirm(chalk.red('Are you sure?'), false);
|
return confirm(client, chalk.red('Are you sure?'), false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -187,6 +187,7 @@ export default async client => {
|
|||||||
if (cardId) {
|
if (cardId) {
|
||||||
const label = `Are you sure that you to set this card as the default?`;
|
const label = `Are you sure that you to set this card as the default?`;
|
||||||
const confirmation = await promptBool(label, {
|
const confirmation = await promptBool(label, {
|
||||||
|
...client,
|
||||||
trailing: '\n',
|
trailing: '\n',
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -262,7 +263,7 @@ export default async client => {
|
|||||||
// typed `vercel billing rm <some-id>`) is valid
|
// typed `vercel billing rm <some-id>`) is valid
|
||||||
if (cardId) {
|
if (cardId) {
|
||||||
const label = `Are you sure that you want to remove this card?`;
|
const label = `Are you sure that you want to remove this card?`;
|
||||||
const confirmation = await promptBool(label);
|
const confirmation = await promptBool(label, client);
|
||||||
if (!confirmation) {
|
if (!confirmation) {
|
||||||
console.log('Aborted');
|
console.log('Aborted');
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -140,6 +140,7 @@ export default async function main(client: Client): Promise<number> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
confirmed = await confirm(
|
confirmed = await confirm(
|
||||||
|
client,
|
||||||
`No Project Settings found locally. Run ${cli.getCommandName(
|
`No Project Settings found locally. Run ${cli.getCommandName(
|
||||||
'pull'
|
'pull'
|
||||||
)} for retrieving them?`,
|
)} for retrieving them?`,
|
||||||
|
|||||||
@@ -165,7 +165,7 @@ export default async (client: Client) => {
|
|||||||
const quiet = !isTTY;
|
const quiet = !isTTY;
|
||||||
|
|
||||||
// check paths
|
// check paths
|
||||||
const pathValidation = await validatePaths(output, paths);
|
const pathValidation = await validatePaths(client, paths);
|
||||||
|
|
||||||
if (!pathValidation.valid) {
|
if (!pathValidation.valid) {
|
||||||
return pathValidation.exitCode;
|
return pathValidation.exitCode;
|
||||||
@@ -243,6 +243,7 @@ export default async (client: Client) => {
|
|||||||
const shouldStartSetup =
|
const shouldStartSetup =
|
||||||
autoConfirm ||
|
autoConfirm ||
|
||||||
(await confirm(
|
(await confirm(
|
||||||
|
client,
|
||||||
`Set up and deploy ${chalk.cyan(`“${toHumanPath(path)}”`)}?`,
|
`Set up and deploy ${chalk.cyan(`“${toHumanPath(path)}”`)}?`,
|
||||||
true
|
true
|
||||||
));
|
));
|
||||||
@@ -287,7 +288,7 @@ export default async (client: Client) => {
|
|||||||
|
|
||||||
if (typeof projectOrNewProjectName === 'string') {
|
if (typeof projectOrNewProjectName === 'string') {
|
||||||
newProjectName = projectOrNewProjectName;
|
newProjectName = projectOrNewProjectName;
|
||||||
rootDirectory = await inputRootDirectory(path, output, autoConfirm);
|
rootDirectory = await inputRootDirectory(client, path, autoConfirm);
|
||||||
} else {
|
} else {
|
||||||
project = projectOrNewProjectName;
|
project = projectOrNewProjectName;
|
||||||
rootDirectory = project.rootDirectory;
|
rootDirectory = project.rootDirectory;
|
||||||
@@ -521,7 +522,7 @@ export default async (client: Client) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const settings = await editProjectSettings(
|
const settings = await editProjectSettings(
|
||||||
output,
|
client,
|
||||||
projectSettings,
|
projectSettings,
|
||||||
framework,
|
framework,
|
||||||
false,
|
false,
|
||||||
|
|||||||
@@ -46,7 +46,7 @@ export default async function add(
|
|||||||
|
|
||||||
const addStamp = stamp();
|
const addStamp = stamp();
|
||||||
const { domain, data: argData } = parsedParams;
|
const { domain, data: argData } = parsedParams;
|
||||||
const data = await getDNSData(output, argData);
|
const data = await getDNSData(client, argData);
|
||||||
if (!data) {
|
if (!data) {
|
||||||
output.log(`Aborted`);
|
output.log(`Aborted`);
|
||||||
return 1;
|
return 1;
|
||||||
|
|||||||
@@ -87,7 +87,8 @@ export default async function buy(
|
|||||||
!(await promptBool(
|
!(await promptBool(
|
||||||
`Buy now for ${chalk.bold(`$${price}`)} (${`${period}yr${
|
`Buy now for ${chalk.bold(`$${price}`)} (${`${period}yr${
|
||||||
period > 1 ? 's' : ''
|
period > 1 ? 's' : ''
|
||||||
}`})?`
|
}`})?`,
|
||||||
|
client
|
||||||
))
|
))
|
||||||
) {
|
) {
|
||||||
return 0;
|
return 0;
|
||||||
@@ -99,7 +100,7 @@ export default async function buy(
|
|||||||
: `Auto renew every ${renewalPrice.period} years for ${chalk.bold(
|
: `Auto renew every ${renewalPrice.period} years for ${chalk.bold(
|
||||||
`$${price}`
|
`$${price}`
|
||||||
)}?`,
|
)}?`,
|
||||||
{ defaultValue: true }
|
{ ...client, defaultValue: true }
|
||||||
);
|
);
|
||||||
|
|
||||||
let buyResult;
|
let buyResult;
|
||||||
|
|||||||
@@ -77,7 +77,8 @@ export default async function move(
|
|||||||
!(await promptBool(
|
!(await promptBool(
|
||||||
`Are you sure you want to move ${param(domainName)} to ${param(
|
`Are you sure you want to move ${param(domainName)} to ${param(
|
||||||
destination
|
destination
|
||||||
)}?`
|
)}?`,
|
||||||
|
client
|
||||||
))
|
))
|
||||||
) {
|
) {
|
||||||
output.log('Aborted');
|
output.log('Aborted');
|
||||||
@@ -95,7 +96,8 @@ export default async function move(
|
|||||||
);
|
);
|
||||||
if (
|
if (
|
||||||
!(await promptBool(
|
!(await promptBool(
|
||||||
`Are you sure you want to move ${param(domainName)}?`
|
`Are you sure you want to move ${param(domainName)}?`,
|
||||||
|
client
|
||||||
))
|
))
|
||||||
) {
|
) {
|
||||||
output.log('Aborted');
|
output.log('Aborted');
|
||||||
|
|||||||
@@ -92,7 +92,10 @@ export default async function rm(
|
|||||||
const skipConfirmation = opts['--yes'] || false;
|
const skipConfirmation = opts['--yes'] || false;
|
||||||
if (
|
if (
|
||||||
!skipConfirmation &&
|
!skipConfirmation &&
|
||||||
!(await promptBool(`Are you sure you want to remove ${param(domainName)}?`))
|
!(await promptBool(
|
||||||
|
`Are you sure you want to remove ${param(domainName)}?`,
|
||||||
|
client
|
||||||
|
))
|
||||||
) {
|
) {
|
||||||
output.log('Aborted');
|
output.log('Aborted');
|
||||||
return 0;
|
return 0;
|
||||||
@@ -230,7 +233,7 @@ async function removeDomain(
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
!skipConfirmation &&
|
!skipConfirmation &&
|
||||||
!(await promptBool(`Remove conflicts associated with domain?`))
|
!(await promptBool(`Remove conflicts associated with domain?`, client))
|
||||||
) {
|
) {
|
||||||
output.log('Aborted');
|
output.log('Aborted');
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -81,7 +81,8 @@ export default async function transferIn(
|
|||||||
const shouldTransfer = await promptBool(
|
const shouldTransfer = await promptBool(
|
||||||
transferPolicy === 'no-change'
|
transferPolicy === 'no-change'
|
||||||
? `Transfer now for ${chalk.bold(`$${price}`)}?`
|
? `Transfer now for ${chalk.bold(`$${price}`)}?`
|
||||||
: `Transfer now with 1yr renewal for ${chalk.bold(`$${price}`)}?`
|
: `Transfer now with 1yr renewal for ${chalk.bold(`$${price}`)}?`,
|
||||||
|
client
|
||||||
);
|
);
|
||||||
if (!shouldTransfer) {
|
if (!shouldTransfer) {
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
2
packages/cli/src/commands/env/add.ts
vendored
2
packages/cli/src/commands/env/add.ts
vendored
@@ -31,7 +31,7 @@ export default async function add(
|
|||||||
// improve the way we show inquirer prompts
|
// improve the way we show inquirer prompts
|
||||||
require('../../util/input/patch-inquirer');
|
require('../../util/input/patch-inquirer');
|
||||||
|
|
||||||
const stdInput = await readStandardInput();
|
const stdInput = await readStandardInput(client.stdin);
|
||||||
let [envName, envTargetArg, envGitBranch] = args;
|
let [envName, envTargetArg, envGitBranch] = args;
|
||||||
|
|
||||||
if (args.length > 3) {
|
if (args.length > 3) {
|
||||||
|
|||||||
1
packages/cli/src/commands/env/pull.ts
vendored
1
packages/cli/src/commands/env/pull.ts
vendored
@@ -74,6 +74,7 @@ export default async function pull(
|
|||||||
exists &&
|
exists &&
|
||||||
!skipConfirmation &&
|
!skipConfirmation &&
|
||||||
!(await confirm(
|
!(await confirm(
|
||||||
|
client,
|
||||||
`Found existing file ${param(filename)}. Do you want to overwrite?`,
|
`Found existing file ${param(filename)}. Do you want to overwrite?`,
|
||||||
false
|
false
|
||||||
))
|
))
|
||||||
|
|||||||
1
packages/cli/src/commands/env/rm.ts
vendored
1
packages/cli/src/commands/env/rm.ts
vendored
@@ -104,6 +104,7 @@ export default async function rm(
|
|||||||
if (
|
if (
|
||||||
!skipConfirmation &&
|
!skipConfirmation &&
|
||||||
!(await confirm(
|
!(await confirm(
|
||||||
|
client,
|
||||||
`Removing Environment Variable ${param(env.key)} from ${formatEnvTarget(
|
`Removing Environment Variable ${param(env.key)} from ${formatEnvTarget(
|
||||||
env
|
env
|
||||||
)} in Project ${chalk.bold(project.name)}. Are you sure?`,
|
)} in Project ${chalk.bold(project.name)}. Are you sure?`,
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ export default async function init(
|
|||||||
return extractExample(client, name, dir, force, 'v1');
|
return extractExample(client, name, dir, force, 'v1');
|
||||||
}
|
}
|
||||||
|
|
||||||
const found = await guess(exampleList, name);
|
const found = await guess(client, exampleList, name);
|
||||||
|
|
||||||
if (typeof found === 'string') {
|
if (typeof found === 'string') {
|
||||||
return extractExample(client, found, dir, force);
|
return extractExample(client, found, dir, force);
|
||||||
@@ -194,7 +194,7 @@ function prepareFolder(cwd: string, folder: string, force?: boolean) {
|
|||||||
/**
|
/**
|
||||||
* Guess which example user try to init
|
* Guess which example user try to init
|
||||||
*/
|
*/
|
||||||
async function guess(exampleList: string[], name: string) {
|
async function guess(client: Client, exampleList: string[], name: string) {
|
||||||
const GuessError = new Error(
|
const GuessError = new Error(
|
||||||
`No example found for ${chalk.bold(name)}, run ${getCommandName(
|
`No example found for ${chalk.bold(name)}, run ${getCommandName(
|
||||||
`init`
|
`init`
|
||||||
@@ -208,7 +208,7 @@ async function guess(exampleList: string[], name: string) {
|
|||||||
const found = didYouMean(name, exampleList, 0.7);
|
const found = didYouMean(name, exampleList, 0.7);
|
||||||
|
|
||||||
if (typeof found === 'string') {
|
if (typeof found === 'string') {
|
||||||
if (await promptBool(`Did you mean ${chalk.bold(found)}?`)) {
|
if (await promptBool(`Did you mean ${chalk.bold(found)}?`, client)) {
|
||||||
return found;
|
return found;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -387,6 +387,8 @@ const main = async () => {
|
|||||||
// Shared API `Client` instance for all sub-commands to utilize
|
// Shared API `Client` instance for all sub-commands to utilize
|
||||||
client = new Client({
|
client = new Client({
|
||||||
apiUrl,
|
apiUrl,
|
||||||
|
stdin: process.stdin,
|
||||||
|
stdout: process.stdout,
|
||||||
output,
|
output,
|
||||||
config,
|
config,
|
||||||
authConfig,
|
authConfig,
|
||||||
|
|||||||
@@ -385,8 +385,14 @@ export async function* findDirs(
|
|||||||
}
|
}
|
||||||
for (const path of paths) {
|
for (const path of paths) {
|
||||||
const abs = join(dir, path);
|
const abs = join(dir, path);
|
||||||
const s = await fs.stat(abs);
|
let stat: fs.Stats;
|
||||||
if (s.isDirectory()) {
|
try {
|
||||||
|
stat = await fs.lstat(abs);
|
||||||
|
} catch (err: any) {
|
||||||
|
if (err.code === 'ENOENT') continue;
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
if (stat.isDirectory()) {
|
||||||
if (path === name) {
|
if (path === name) {
|
||||||
yield relative(root, abs);
|
yield relative(root, abs);
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -32,6 +32,8 @@ export interface ClientOptions {
|
|||||||
argv: string[];
|
argv: string[];
|
||||||
apiUrl: string;
|
apiUrl: string;
|
||||||
authConfig: AuthConfig;
|
authConfig: AuthConfig;
|
||||||
|
stdin: NodeJS.ReadStream;
|
||||||
|
stdout: NodeJS.WriteStream;
|
||||||
output: Output;
|
output: Output;
|
||||||
config: GlobalConfig;
|
config: GlobalConfig;
|
||||||
localConfig?: VercelConfig;
|
localConfig?: VercelConfig;
|
||||||
@@ -45,6 +47,8 @@ export default class Client extends EventEmitter {
|
|||||||
argv: string[];
|
argv: string[];
|
||||||
apiUrl: string;
|
apiUrl: string;
|
||||||
authConfig: AuthConfig;
|
authConfig: AuthConfig;
|
||||||
|
stdin: NodeJS.ReadStream;
|
||||||
|
stdout: NodeJS.WriteStream;
|
||||||
output: Output;
|
output: Output;
|
||||||
config: GlobalConfig;
|
config: GlobalConfig;
|
||||||
localConfig?: VercelConfig;
|
localConfig?: VercelConfig;
|
||||||
@@ -55,6 +59,8 @@ export default class Client extends EventEmitter {
|
|||||||
this.argv = opts.argv;
|
this.argv = opts.argv;
|
||||||
this.apiUrl = opts.apiUrl;
|
this.apiUrl = opts.apiUrl;
|
||||||
this.authConfig = opts.authConfig;
|
this.authConfig = opts.authConfig;
|
||||||
|
this.stdin = opts.stdin;
|
||||||
|
this.stdout = opts.stdout;
|
||||||
this.output = opts.output;
|
this.output = opts.output;
|
||||||
this.config = opts.config;
|
this.config = opts.config;
|
||||||
this.localConfig = opts.localConfig;
|
this.localConfig = opts.localConfig;
|
||||||
|
|||||||
@@ -329,6 +329,8 @@ export default class DevServer {
|
|||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
const name = relative(this.cwd, fsPath);
|
const name = relative(this.cwd, fsPath);
|
||||||
try {
|
try {
|
||||||
|
await this.getVercelConfig();
|
||||||
|
|
||||||
this.files[name] = await FileFsRef.fromFsPath({ fsPath });
|
this.files[name] = await FileFsRef.fromFsPath({ fsPath });
|
||||||
const extensionless = this.getExtensionlessFile(name);
|
const extensionless = this.getExtensionlessFile(name);
|
||||||
if (extensionless) {
|
if (extensionless) {
|
||||||
|
|||||||
@@ -2,26 +2,29 @@ import chalk from 'chalk';
|
|||||||
import { DNSRecordData } from '../../types';
|
import { DNSRecordData } from '../../types';
|
||||||
import textInput from '../input/text';
|
import textInput from '../input/text';
|
||||||
import promptBool from '../input/prompt-bool';
|
import promptBool from '../input/prompt-bool';
|
||||||
import { Output } from '../output';
|
import Client from '../client';
|
||||||
|
|
||||||
const RECORD_TYPES = ['A', 'AAAA', 'ALIAS', 'CAA', 'CNAME', 'MX', 'SRV', 'TXT'];
|
const RECORD_TYPES = ['A', 'AAAA', 'ALIAS', 'CAA', 'CNAME', 'MX', 'SRV', 'TXT'];
|
||||||
|
|
||||||
export default async function getDNSData(
|
export default async function getDNSData(
|
||||||
output: Output,
|
client: Client,
|
||||||
data: null | DNSRecordData
|
data: null | DNSRecordData
|
||||||
): Promise<DNSRecordData | null> {
|
): Promise<DNSRecordData | null> {
|
||||||
if (data) {
|
if (data) {
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
const { output } = client;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// first ask for type, branch from there
|
// first ask for type, branch from there
|
||||||
const possibleTypes = new Set(RECORD_TYPES);
|
const possibleTypes = new Set(RECORD_TYPES);
|
||||||
const type = (await textInput({
|
const type = (
|
||||||
label: `- Record type (${RECORD_TYPES.join(', ')}): `,
|
await textInput({
|
||||||
validateValue: (v: string) =>
|
label: `- Record type (${RECORD_TYPES.join(', ')}): `,
|
||||||
Boolean(v && possibleTypes.has(v.trim().toUpperCase()))
|
validateValue: (v: string) =>
|
||||||
}))
|
Boolean(v && possibleTypes.has(v.trim().toUpperCase())),
|
||||||
|
})
|
||||||
|
)
|
||||||
.trim()
|
.trim()
|
||||||
.toUpperCase();
|
.toUpperCase();
|
||||||
|
|
||||||
@@ -39,7 +42,7 @@ export default async function getDNSData(
|
|||||||
target
|
target
|
||||||
)}.`
|
)}.`
|
||||||
);
|
);
|
||||||
return (await verifyData())
|
return (await verifyData(client))
|
||||||
? {
|
? {
|
||||||
name,
|
name,
|
||||||
type,
|
type,
|
||||||
@@ -47,8 +50,8 @@ export default async function getDNSData(
|
|||||||
priority,
|
priority,
|
||||||
weight,
|
weight,
|
||||||
port,
|
port,
|
||||||
target
|
target,
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
@@ -61,23 +64,23 @@ export default async function getDNSData(
|
|||||||
`${mxPriority}`
|
`${mxPriority}`
|
||||||
)} ${chalk.cyan(value)}`
|
)} ${chalk.cyan(value)}`
|
||||||
);
|
);
|
||||||
return (await verifyData())
|
return (await verifyData(client))
|
||||||
? {
|
? {
|
||||||
name,
|
name,
|
||||||
type,
|
type,
|
||||||
value,
|
value,
|
||||||
mxPriority
|
mxPriority,
|
||||||
}
|
}
|
||||||
: null;
|
: null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const value = await getTrimmedString(`- ${type} value: `);
|
const value = await getTrimmedString(`- ${type} value: `);
|
||||||
output.log(`${chalk.cyan(name)} ${chalk.bold(type)} ${chalk.cyan(value)}`);
|
output.log(`${chalk.cyan(name)} ${chalk.bold(type)} ${chalk.cyan(value)}`);
|
||||||
return (await verifyData())
|
return (await verifyData(client))
|
||||||
? {
|
? {
|
||||||
name,
|
name,
|
||||||
type,
|
type,
|
||||||
value
|
value,
|
||||||
}
|
}
|
||||||
: null;
|
: null;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -85,13 +88,13 @@ export default async function getDNSData(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function verifyData() {
|
async function verifyData(client: Client) {
|
||||||
return promptBool('Is this correct?');
|
return promptBool('Is this correct?', client);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getRecordName(type: string) {
|
async function getRecordName(type: string) {
|
||||||
const input = await textInput({
|
const input = await textInput({
|
||||||
label: `- ${type} name: `
|
label: `- ${type} name: `,
|
||||||
});
|
});
|
||||||
return input === '@' ? '' : input;
|
return input === '@' ? '' : input;
|
||||||
}
|
}
|
||||||
@@ -100,14 +103,14 @@ async function getNumber(label: string) {
|
|||||||
return Number(
|
return Number(
|
||||||
await textInput({
|
await textInput({
|
||||||
label,
|
label,
|
||||||
validateValue: v => Boolean(v && Number(v))
|
validateValue: v => Boolean(v && Number(v)),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
async function getTrimmedString(label: string) {
|
async function getTrimmedString(label: string) {
|
||||||
const res = await textInput({
|
const res = await textInput({
|
||||||
label,
|
label,
|
||||||
validateValue: v => Boolean(v && v.trim().length > 0)
|
validateValue: v => Boolean(v && v.trim().length > 0),
|
||||||
});
|
});
|
||||||
return res.trim();
|
return res.trim();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -54,7 +54,8 @@ export default async function purchaseDomainIfAvailable(
|
|||||||
!(await promptBool(
|
!(await promptBool(
|
||||||
`Buy ${chalk.underline(domain)} for ${chalk.bold(
|
`Buy ${chalk.underline(domain)} for ${chalk.bold(
|
||||||
`$${price}`
|
`$${price}`
|
||||||
)} (${plural('yr', period, true)})?`
|
)} (${plural('yr', period, true)})?`,
|
||||||
|
client
|
||||||
))
|
))
|
||||||
) {
|
) {
|
||||||
output.print(eraseLines(1));
|
output.print(eraseLines(1));
|
||||||
|
|||||||
@@ -1,12 +1,19 @@
|
|||||||
import inquirer from 'inquirer';
|
import inquirer from 'inquirer';
|
||||||
|
import Client from '../client';
|
||||||
|
|
||||||
export default async function confirm(
|
export default async function confirm(
|
||||||
|
client: Client,
|
||||||
message: string,
|
message: string,
|
||||||
preferred: boolean
|
preferred: boolean
|
||||||
): Promise<boolean> {
|
): Promise<boolean> {
|
||||||
require('./patch-inquirer');
|
require('./patch-inquirer');
|
||||||
|
|
||||||
const answers = await inquirer.prompt({
|
const prompt = inquirer.createPromptModule({
|
||||||
|
input: client.stdin,
|
||||||
|
output: client.stdout,
|
||||||
|
});
|
||||||
|
|
||||||
|
const answers = await prompt({
|
||||||
type: 'confirm',
|
type: 'confirm',
|
||||||
name: 'value',
|
name: 'value',
|
||||||
message,
|
message,
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import inquirer from 'inquirer';
|
import inquirer from 'inquirer';
|
||||||
import confirm from './confirm';
|
import confirm from './confirm';
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
import { Output } from '../output';
|
|
||||||
import frameworkList, { Framework } from '@vercel/frameworks';
|
import frameworkList, { Framework } from '@vercel/frameworks';
|
||||||
|
import Client from '../client';
|
||||||
import { isSettingValue } from '../is-setting-value';
|
import { isSettingValue } from '../is-setting-value';
|
||||||
import { ProjectSettings } from '../../types';
|
import { ProjectSettings } from '../../types';
|
||||||
|
|
||||||
@@ -22,12 +22,14 @@ const settingKeys = Object.keys(settingMap).sort() as unknown as readonly [
|
|||||||
export type PartialProjectSettings = Pick<ProjectSettings, ConfigKeys>;
|
export type PartialProjectSettings = Pick<ProjectSettings, ConfigKeys>;
|
||||||
|
|
||||||
export default async function editProjectSettings(
|
export default async function editProjectSettings(
|
||||||
output: Output,
|
client: Client,
|
||||||
projectSettings: PartialProjectSettings | null,
|
projectSettings: PartialProjectSettings | null,
|
||||||
framework: Framework | null,
|
framework: Framework | null,
|
||||||
autoConfirm: boolean,
|
autoConfirm: boolean,
|
||||||
localConfigurationOverrides: PartialProjectSettings | null
|
localConfigurationOverrides: PartialProjectSettings | null
|
||||||
): Promise<ProjectSettings> {
|
): Promise<ProjectSettings> {
|
||||||
|
const { output } = client;
|
||||||
|
|
||||||
// Create initial settings object defaulting everything to `null` and assigning what may exist in `projectSettings`
|
// Create initial settings object defaulting everything to `null` and assigning what may exist in `projectSettings`
|
||||||
const settings: ProjectSettings = Object.assign(
|
const settings: ProjectSettings = Object.assign(
|
||||||
{
|
{
|
||||||
@@ -118,7 +120,7 @@ export default async function editProjectSettings(
|
|||||||
// Prompt the user if they want to modify any settings not defined by local configuration.
|
// Prompt the user if they want to modify any settings not defined by local configuration.
|
||||||
if (
|
if (
|
||||||
autoConfirm ||
|
autoConfirm ||
|
||||||
!(await confirm('Want to modify these settings?', false))
|
!(await confirm(client, 'Want to modify these settings?', false))
|
||||||
) {
|
) {
|
||||||
return settings;
|
return settings;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,11 +47,16 @@ export default async function inputProject(
|
|||||||
|
|
||||||
if (!detectedProject) {
|
if (!detectedProject) {
|
||||||
// did not auto-detect a project to link
|
// did not auto-detect a project to link
|
||||||
shouldLinkProject = await confirm(`Link to existing project?`, false);
|
shouldLinkProject = await confirm(
|
||||||
|
client,
|
||||||
|
`Link to existing project?`,
|
||||||
|
false
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
// auto-detected a project to link
|
// auto-detected a project to link
|
||||||
if (
|
if (
|
||||||
await confirm(
|
await confirm(
|
||||||
|
client,
|
||||||
`Found project ${chalk.cyan(
|
`Found project ${chalk.cyan(
|
||||||
`“${org.slug}/${detectedProject.name}”`
|
`“${org.slug}/${detectedProject.name}”`
|
||||||
)}. Link to it?`,
|
)}. Link to it?`,
|
||||||
@@ -63,6 +68,7 @@ export default async function inputProject(
|
|||||||
|
|
||||||
// user doesn't want to link the auto-detected project
|
// user doesn't want to link the auto-detected project
|
||||||
shouldLinkProject = await confirm(
|
shouldLinkProject = await confirm(
|
||||||
|
client,
|
||||||
`Link to different existing project?`,
|
`Link to different existing project?`,
|
||||||
true
|
true
|
||||||
);
|
);
|
||||||
@@ -73,7 +79,11 @@ export default async function inputProject(
|
|||||||
let project: Project | ProjectNotFound | null = null;
|
let project: Project | ProjectNotFound | null = null;
|
||||||
|
|
||||||
while (!project || project instanceof ProjectNotFound) {
|
while (!project || project instanceof ProjectNotFound) {
|
||||||
const answers = await inquirer.prompt({
|
const prompt = inquirer.createPromptModule({
|
||||||
|
input: client.stdin,
|
||||||
|
output: client.stdout,
|
||||||
|
});
|
||||||
|
const answers = await prompt({
|
||||||
type: 'input',
|
type: 'input',
|
||||||
name: 'existingProjectName',
|
name: 'existingProjectName',
|
||||||
message: `What’s the name of your existing project?`,
|
message: `What’s the name of your existing project?`,
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import path from 'path';
|
import path from 'path';
|
||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
import inquirer from 'inquirer';
|
import inquirer from 'inquirer';
|
||||||
import { Output } from '../output';
|
|
||||||
import { validateRootDirectory } from '../validate-paths';
|
import { validateRootDirectory } from '../validate-paths';
|
||||||
|
import Client from '../client';
|
||||||
|
|
||||||
export async function inputRootDirectory(
|
export async function inputRootDirectory(
|
||||||
|
client: Client,
|
||||||
cwd: string,
|
cwd: string,
|
||||||
output: Output,
|
|
||||||
autoConfirm = false
|
autoConfirm = false
|
||||||
) {
|
) {
|
||||||
if (autoConfirm) {
|
if (autoConfirm) {
|
||||||
@@ -15,7 +15,11 @@ export async function inputRootDirectory(
|
|||||||
|
|
||||||
// eslint-disable-next-line no-constant-condition
|
// eslint-disable-next-line no-constant-condition
|
||||||
while (true) {
|
while (true) {
|
||||||
const { rootDirectory } = await inquirer.prompt({
|
const prompt = inquirer.createPromptModule({
|
||||||
|
input: client.stdin,
|
||||||
|
output: client.stdout,
|
||||||
|
});
|
||||||
|
const { rootDirectory } = await prompt({
|
||||||
type: 'input',
|
type: 'input',
|
||||||
name: 'rootDirectory',
|
name: 'rootDirectory',
|
||||||
message: `In which directory is your code located?`,
|
message: `In which directory is your code located?`,
|
||||||
@@ -38,7 +42,7 @@ export async function inputRootDirectory(
|
|||||||
|
|
||||||
if (
|
if (
|
||||||
(await validateRootDirectory(
|
(await validateRootDirectory(
|
||||||
output,
|
client.output,
|
||||||
cwd,
|
cwd,
|
||||||
fullPath,
|
fullPath,
|
||||||
'Please choose a different one.'
|
'Please choose a different one.'
|
||||||
|
|||||||
@@ -5,21 +5,21 @@ type Options = {
|
|||||||
defaultValue?: boolean;
|
defaultValue?: boolean;
|
||||||
noChar?: string;
|
noChar?: string;
|
||||||
resolveChars?: Set<string>;
|
resolveChars?: Set<string>;
|
||||||
stdin?: NodeJS.ReadStream;
|
stdin: NodeJS.ReadStream;
|
||||||
stdout?: NodeJS.WriteStream;
|
stdout: NodeJS.WriteStream;
|
||||||
trailing?: string;
|
trailing?: string;
|
||||||
yesChar?: string;
|
yesChar?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default async function promptBool(label: string, options: Options = {}) {
|
export default async function promptBool(label: string, options: Options) {
|
||||||
const {
|
const {
|
||||||
|
stdin,
|
||||||
|
stdout,
|
||||||
defaultValue = false,
|
defaultValue = false,
|
||||||
abortSequences = new Set(['\u0003']),
|
abortSequences = new Set(['\u0003']),
|
||||||
resolveChars = new Set(['\r']),
|
resolveChars = new Set(['\r']),
|
||||||
yesChar = 'y',
|
yesChar = 'y',
|
||||||
noChar = 'n',
|
noChar = 'n',
|
||||||
stdin = process.stdin,
|
|
||||||
stdout = process.stdout,
|
|
||||||
trailing = '',
|
trailing = '',
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
export default async function readStandardInput(): Promise<string> {
|
export default async function readStandardInput(
|
||||||
|
stdin: NodeJS.ReadStream
|
||||||
|
): Promise<string> {
|
||||||
return new Promise<string>(resolve => {
|
return new Promise<string>(resolve => {
|
||||||
setTimeout(() => resolve(''), 500);
|
setTimeout(() => resolve(''), 500);
|
||||||
|
|
||||||
if (process.stdin.isTTY) {
|
if (stdin.isTTY) {
|
||||||
// found tty so we know there is nothing piped to stdin
|
// found tty so we know there is nothing piped to stdin
|
||||||
resolve('');
|
resolve('');
|
||||||
} else {
|
} else {
|
||||||
process.stdin.setEncoding('utf8');
|
stdin.setEncoding('utf8');
|
||||||
process.stdin.once('data', resolve);
|
stdin.once('data', resolve);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,6 +80,7 @@ export default async function setupAndLink(
|
|||||||
const shouldStartSetup =
|
const shouldStartSetup =
|
||||||
autoConfirm ||
|
autoConfirm ||
|
||||||
(await confirm(
|
(await confirm(
|
||||||
|
client,
|
||||||
`${setupMsg} ${chalk.cyan(`“${toHumanPath(path)}”`)}?`,
|
`${setupMsg} ${chalk.cyan(`“${toHumanPath(path)}”`)}?`,
|
||||||
true
|
true
|
||||||
));
|
));
|
||||||
@@ -120,7 +121,7 @@ export default async function setupAndLink(
|
|||||||
|
|
||||||
if (typeof projectOrNewProjectName === 'string') {
|
if (typeof projectOrNewProjectName === 'string') {
|
||||||
newProjectName = projectOrNewProjectName;
|
newProjectName = projectOrNewProjectName;
|
||||||
rootDirectory = await inputRootDirectory(path, output, autoConfirm);
|
rootDirectory = await inputRootDirectory(client, path, autoConfirm);
|
||||||
} else {
|
} else {
|
||||||
const project = projectOrNewProjectName;
|
const project = projectOrNewProjectName;
|
||||||
|
|
||||||
@@ -224,7 +225,7 @@ export default async function setupAndLink(
|
|||||||
const { projectSettings, framework } = deployment;
|
const { projectSettings, framework } = deployment;
|
||||||
|
|
||||||
settings = await editProjectSettings(
|
settings = await editProjectSettings(
|
||||||
output,
|
client,
|
||||||
projectSettings,
|
projectSettings,
|
||||||
framework,
|
framework,
|
||||||
autoConfirm,
|
autoConfirm,
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ export default async function reauthenticate(
|
|||||||
client.output.log(
|
client.output.log(
|
||||||
`You must re-authenticate with SAML to use ${bold(error.scope)} scope.`
|
`You must re-authenticate with SAML to use ${bold(error.scope)} scope.`
|
||||||
);
|
);
|
||||||
if (await confirm(`Log in with SAML?`, true)) {
|
if (await confirm(client, `Log in with SAML?`, true)) {
|
||||||
return doSamlLogin(client, error.teamId);
|
return doSamlLogin(client, error.teamId);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import chalk from 'chalk';
|
|||||||
import { homedir } from 'os';
|
import { homedir } from 'os';
|
||||||
import confirm from './input/confirm';
|
import confirm from './input/confirm';
|
||||||
import toHumanPath from './humanize-path';
|
import toHumanPath from './humanize-path';
|
||||||
|
import Client from './client';
|
||||||
|
|
||||||
const stat = promisify(lstatRaw);
|
const stat = promisify(lstatRaw);
|
||||||
|
|
||||||
@@ -51,9 +52,11 @@ export async function validateRootDirectory(
|
|||||||
}
|
}
|
||||||
|
|
||||||
export default async function validatePaths(
|
export default async function validatePaths(
|
||||||
output: Output,
|
client: Client,
|
||||||
paths: string[]
|
paths: string[]
|
||||||
): Promise<{ valid: true; path: string } | { valid: false; exitCode: number }> {
|
): Promise<{ valid: true; path: string } | { valid: false; exitCode: number }> {
|
||||||
|
const { output } = client;
|
||||||
|
|
||||||
// can't deploy more than 1 path
|
// can't deploy more than 1 path
|
||||||
if (paths.length > 1) {
|
if (paths.length > 1) {
|
||||||
output.print(`${chalk.red('Error!')} Can't deploy more than one path.\n`);
|
output.print(`${chalk.red('Error!')} Can't deploy more than one path.\n`);
|
||||||
@@ -85,6 +88,7 @@ export default async function validatePaths(
|
|||||||
// ask confirmation if the directory is home
|
// ask confirmation if the directory is home
|
||||||
if (path === homedir()) {
|
if (path === homedir()) {
|
||||||
const shouldDeployHomeDirectory = await confirm(
|
const shouldDeployHomeDirectory = await confirm(
|
||||||
|
client,
|
||||||
`You are deploying your home directory. Do you want to continue?`,
|
`You are deploying your home directory. Do you want to continue?`,
|
||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ export const config = {
|
|||||||
runtime: 'experimental-edge'
|
runtime: 'experimental-edge'
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async function edge(request: Request, event: Event) {
|
export default async function edge(request, event) {
|
||||||
return new Response('some response body');
|
return new Response('some response body');
|
||||||
|
|
||||||
// intentional missing closing bracket to produce syntax error
|
// intentional missing closing bracket to produce syntax error
|
||||||
|
|||||||
3
packages/cli/test/dev/fixtures/no-api/vercel.json
Normal file
3
packages/cli/test/dev/fixtures/no-api/vercel.json
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"version": 2
|
||||||
|
}
|
||||||
@@ -161,14 +161,13 @@ test('[vercel dev] should handle startup errors thrown in edge functions', async
|
|||||||
});
|
});
|
||||||
validateResponseHeaders(res);
|
validateResponseHeaders(res);
|
||||||
|
|
||||||
const { stdout, stderr } = await dev.kill('SIGTERM');
|
const { stderr } = await dev.kill('SIGTERM');
|
||||||
|
|
||||||
expect(await res.text()).toMatch(
|
expect(await res.text()).toMatch(
|
||||||
/<strong>500<\/strong>: INTERNAL_SERVER_ERROR/g
|
/<strong>500<\/strong>: INTERNAL_SERVER_ERROR/g
|
||||||
);
|
);
|
||||||
expect(stdout).toMatch(
|
expect(stderr).toMatch(/Failed to instantiate edge runtime./g);
|
||||||
/Failed to instantiate edge runtime: intentional startup error/g
|
expect(stderr).toMatch(/intentional startup error/g);
|
||||||
);
|
|
||||||
expect(stderr).toMatch(
|
expect(stderr).toMatch(
|
||||||
/Failed to complete request to \/api\/edge-error-startup: Error: socket hang up/g
|
/Failed to complete request to \/api\/edge-error-startup: Error: socket hang up/g
|
||||||
);
|
);
|
||||||
@@ -193,14 +192,13 @@ test('[vercel dev] should handle syntax errors thrown in edge functions', async
|
|||||||
});
|
});
|
||||||
validateResponseHeaders(res);
|
validateResponseHeaders(res);
|
||||||
|
|
||||||
const { stdout, stderr } = await dev.kill('SIGTERM');
|
const { stderr } = await dev.kill('SIGTERM');
|
||||||
|
|
||||||
expect(await res.text()).toMatch(
|
expect(await res.text()).toMatch(
|
||||||
/<strong>500<\/strong>: INTERNAL_SERVER_ERROR/g
|
/<strong>500<\/strong>: INTERNAL_SERVER_ERROR/g
|
||||||
);
|
);
|
||||||
expect(stdout).toMatch(
|
expect(stderr).toMatch(/Failed to instantiate edge runtime./g);
|
||||||
/Failed to instantiate edge runtime: Module parse failed: Unexpected token/g
|
expect(stderr).toMatch(/Unexpected end of file/g);
|
||||||
);
|
|
||||||
expect(stderr).toMatch(
|
expect(stderr).toMatch(
|
||||||
/Failed to complete request to \/api\/edge-error-syntax: Error: socket hang up/g
|
/Failed to complete request to \/api\/edge-error-syntax: Error: socket hang up/g
|
||||||
);
|
);
|
||||||
@@ -228,13 +226,13 @@ test('[vercel dev] should handle import errors thrown in edge functions', async
|
|||||||
);
|
);
|
||||||
validateResponseHeaders(res);
|
validateResponseHeaders(res);
|
||||||
|
|
||||||
const { stdout, stderr } = await dev.kill('SIGTERM');
|
const { stderr } = await dev.kill('SIGTERM');
|
||||||
|
|
||||||
expect(await res.text()).toMatch(
|
expect(await res.text()).toMatch(
|
||||||
/<strong>500<\/strong>: INTERNAL_SERVER_ERROR/g
|
/<strong>500<\/strong>: INTERNAL_SERVER_ERROR/g
|
||||||
);
|
);
|
||||||
expect(stdout).toMatch(
|
expect(stderr).toMatch(
|
||||||
/Failed to instantiate edge runtime: Code generation from strings disallowed for this context/g
|
/Could not resolve "unknown-module-893427589372458934795843"/g
|
||||||
);
|
);
|
||||||
expect(stderr).toMatch(
|
expect(stderr).toMatch(
|
||||||
/Failed to complete request to \/api\/edge-error-unknown-import: Error: socket hang up/g
|
/Failed to complete request to \/api\/edge-error-unknown-import: Error: socket hang up/g
|
||||||
@@ -244,7 +242,7 @@ test('[vercel dev] should handle import errors thrown in edge functions', async
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('[vercel dev] should handle import errors thrown in edge functions', async () => {
|
test('[vercel dev] should handle missing handler errors thrown in edge functions', async () => {
|
||||||
const dir = fixture('edge-function-error');
|
const dir = fixture('edge-function-error');
|
||||||
const { dev, port, readyResolver } = await testFixture(dir);
|
const { dev, port, readyResolver } = await testFixture(dir);
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,17 @@
|
|||||||
// eslint-disable-next-line
|
// eslint-disable-next-line
|
||||||
import path from 'path';
|
import { join } from 'path';
|
||||||
|
import ms from 'ms';
|
||||||
|
import fs, { mkdirp } from 'fs-extra';
|
||||||
|
|
||||||
const { exec, fixture, testFixture, testFixtureStdio } = require('./utils.js');
|
const {
|
||||||
|
exec,
|
||||||
|
fetch,
|
||||||
|
fixture,
|
||||||
|
sleep,
|
||||||
|
testFixture,
|
||||||
|
testFixtureStdio,
|
||||||
|
validateResponseHeaders,
|
||||||
|
} = require('./utils.js');
|
||||||
|
|
||||||
test('[vercel dev] validate redirects', async () => {
|
test('[vercel dev] validate redirects', async () => {
|
||||||
const directory = fixture('invalid-redirects');
|
const directory = fixture('invalid-redirects');
|
||||||
@@ -334,3 +344,44 @@ test(
|
|||||||
await testPath(200, '/', /A simple deployment with the Vercel API!/m);
|
await testPath(200, '/', /A simple deployment with the Vercel API!/m);
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
test(
|
||||||
|
'[vercel dev] add a `api/fn.ts` when `api` does not exist at startup`',
|
||||||
|
testFixtureStdio('no-api', async (_testPath: any, port: any) => {
|
||||||
|
const directory = fixture('no-api');
|
||||||
|
const apiDir = join(directory, 'api');
|
||||||
|
|
||||||
|
try {
|
||||||
|
{
|
||||||
|
const response = await fetch(`http://localhost:${port}/api/new-file`);
|
||||||
|
validateResponseHeaders(response);
|
||||||
|
expect(response.status).toBe(404);
|
||||||
|
}
|
||||||
|
|
||||||
|
const fileContents = `
|
||||||
|
export const config = {
|
||||||
|
runtime: 'experimental-edge'
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async function edge(request, event) {
|
||||||
|
return new Response('from new file');
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
await mkdirp(apiDir);
|
||||||
|
await fs.writeFile(join(apiDir, 'new-file.js'), fileContents);
|
||||||
|
|
||||||
|
// Wait until file events have been processed
|
||||||
|
await sleep(ms('1s'));
|
||||||
|
|
||||||
|
{
|
||||||
|
const response = await fetch(`http://localhost:${port}/api/new-file`);
|
||||||
|
validateResponseHeaders(response);
|
||||||
|
const body = await response.text();
|
||||||
|
expect(body.trim()).toBe('from new file');
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
await fs.remove(apiDir);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|||||||
@@ -508,18 +508,10 @@ test(
|
|||||||
|
|
||||||
test(
|
test(
|
||||||
'[vercel dev] Middleware with `matchers` config',
|
'[vercel dev] Middleware with `matchers` config',
|
||||||
testFixtureStdio(
|
testFixtureStdio('middleware-matchers', async (testPath: any) => {
|
||||||
'middleware-matchers',
|
await testPath(404, '/');
|
||||||
async (testPath: any) => {
|
await testPath(404, '/another');
|
||||||
// TODO: remove once latest `@vercel/node` is shipped to stable with `matchers` support (fails because `directoryListing`)
|
await testPath(200, '/about/page', 'middleware response');
|
||||||
//await testPath(404, '/');
|
await testPath(200, '/dashboard/home', 'middleware response');
|
||||||
await testPath(404, '/another');
|
})
|
||||||
await testPath(200, '/about/page', 'middleware response');
|
|
||||||
await testPath(200, '/dashboard/home', 'middleware response');
|
|
||||||
},
|
|
||||||
{
|
|
||||||
// TODO: remove once latest `@vercel/node` is shipped to stable with `matchers` support
|
|
||||||
skipDeploy: true,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import chalk from 'chalk';
|
import chalk from 'chalk';
|
||||||
|
import { PassThrough } from 'stream';
|
||||||
import { createServer, Server } from 'http';
|
import { createServer, Server } from 'http';
|
||||||
import express, { Express, Router } from 'express';
|
import express, { Express, Router } from 'express';
|
||||||
import listen from 'async-listen';
|
import listen from 'async-listen';
|
||||||
@@ -23,10 +24,13 @@ export class MockClient extends Client {
|
|||||||
// Gets populated in `startMockServer()`
|
// Gets populated in `startMockServer()`
|
||||||
apiUrl: '',
|
apiUrl: '',
|
||||||
authConfig: {},
|
authConfig: {},
|
||||||
|
stdin: new PassThrough(),
|
||||||
|
stdout: new PassThrough(),
|
||||||
output: new Output(),
|
output: new Output(),
|
||||||
config: {},
|
config: {},
|
||||||
localConfig: {},
|
localConfig: {},
|
||||||
});
|
});
|
||||||
|
|
||||||
this.mockOutput = jest.fn();
|
this.mockOutput = jest.fn();
|
||||||
|
|
||||||
this.app = express();
|
this.app = express();
|
||||||
@@ -53,6 +57,12 @@ export class MockClient extends Client {
|
|||||||
}
|
}
|
||||||
|
|
||||||
reset() {
|
reset() {
|
||||||
|
this.stdin = new PassThrough();
|
||||||
|
this.stdin.isTTY = true;
|
||||||
|
|
||||||
|
this.stdout = new PassThrough();
|
||||||
|
this.stdout.isTTY = true;
|
||||||
|
|
||||||
this.output = new Output();
|
this.output = new Output();
|
||||||
this.mockOutput = jest.fn();
|
this.mockOutput = jest.fn();
|
||||||
this.output.print = s => {
|
this.output.print = s => {
|
||||||
|
|||||||
25
packages/cli/test/unit/mock.test.ts
Normal file
25
packages/cli/test/unit/mock.test.ts
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
import confirm from '../../src/util/input/confirm';
|
||||||
|
import { client } from '../mocks/client';
|
||||||
|
|
||||||
|
describe('MockClient', () => {
|
||||||
|
it('should mock `confirm()`', async () => {
|
||||||
|
// true
|
||||||
|
let confirmedPromise = confirm(client, 'Do the thing?', false);
|
||||||
|
|
||||||
|
client.stdin.write('yes\n');
|
||||||
|
|
||||||
|
client.stdout.setEncoding('utf8');
|
||||||
|
client.stdout.on('data', d => console.log({ d }));
|
||||||
|
|
||||||
|
let confirmed = await confirmedPromise;
|
||||||
|
expect(confirmed).toEqual(true);
|
||||||
|
|
||||||
|
// false
|
||||||
|
confirmedPromise = confirm(client, 'Do the thing?', false);
|
||||||
|
|
||||||
|
client.stdin.write('no\n');
|
||||||
|
|
||||||
|
confirmed = await confirmedPromise;
|
||||||
|
expect(confirmed).toEqual(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,13 +1,6 @@
|
|||||||
import { Framework, frameworks } from '@vercel/frameworks';
|
import { Framework, frameworks } from '@vercel/frameworks';
|
||||||
import editProjectSettings from '../../../../src/util/input/edit-project-settings';
|
import editProjectSettings from '../../../../src/util/input/edit-project-settings';
|
||||||
import { Output } from '../../../../src/util/output';
|
import { client } from '../../../mocks/client';
|
||||||
|
|
||||||
let output: Output;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
|
||||||
output = new Output();
|
|
||||||
output.print = jest.fn();
|
|
||||||
});
|
|
||||||
|
|
||||||
const otherFramework = frameworks.find(
|
const otherFramework = frameworks.find(
|
||||||
fwk => fwk.name === 'Other'
|
fwk => fwk.name === 'Other'
|
||||||
@@ -20,7 +13,7 @@ describe('editProjectSettings', () => {
|
|||||||
describe('with no settings, "Other" framework, and no overrides provided', () => {
|
describe('with no settings, "Other" framework, and no overrides provided', () => {
|
||||||
test('should default all settings to `null` and print user default framework settings', async () => {
|
test('should default all settings to `null` and print user default framework settings', async () => {
|
||||||
const settings = await editProjectSettings(
|
const settings = await editProjectSettings(
|
||||||
output,
|
client,
|
||||||
null,
|
null,
|
||||||
otherFramework,
|
otherFramework,
|
||||||
true,
|
true,
|
||||||
@@ -34,22 +27,14 @@ describe('editProjectSettings', () => {
|
|||||||
installCommand: null,
|
installCommand: null,
|
||||||
outputDirectory: null,
|
outputDirectory: null,
|
||||||
});
|
});
|
||||||
expect((output.print as jest.Mock).mock.calls.length).toBe(5);
|
expect(client.mockOutput.mock.calls.length).toBe(5);
|
||||||
expect((output.print as jest.Mock).mock.calls[0][0]).toMatch(
|
expect(client.mockOutput.mock.calls[0][0]).toMatch(
|
||||||
/No framework detected. Default Project Settings:/
|
/No framework detected. Default Project Settings:/
|
||||||
);
|
);
|
||||||
expect((output.print as jest.Mock).mock.calls[1][0]).toMatch(
|
expect(client.mockOutput.mock.calls[1][0]).toMatch(/Build Command/);
|
||||||
/Build Command/
|
expect(client.mockOutput.mock.calls[2][0]).toMatch(/Development Command/);
|
||||||
);
|
expect(client.mockOutput.mock.calls[3][0]).toMatch(/Install Command/);
|
||||||
expect((output.print as jest.Mock).mock.calls[2][0]).toMatch(
|
expect(client.mockOutput.mock.calls[4][0]).toMatch(/Output Directory/);
|
||||||
/Development Command/
|
|
||||||
);
|
|
||||||
expect((output.print as jest.Mock).mock.calls[3][0]).toMatch(
|
|
||||||
/Install Command/
|
|
||||||
);
|
|
||||||
expect((output.print as jest.Mock).mock.calls[4][0]).toMatch(
|
|
||||||
/Output Directory/
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -63,29 +48,21 @@ describe('editProjectSettings', () => {
|
|||||||
outputDirectory: 'OUTPUT_DIRECTORY',
|
outputDirectory: 'OUTPUT_DIRECTORY',
|
||||||
};
|
};
|
||||||
const settings = await editProjectSettings(
|
const settings = await editProjectSettings(
|
||||||
output,
|
client,
|
||||||
projectSettings,
|
projectSettings,
|
||||||
otherFramework,
|
otherFramework,
|
||||||
true,
|
true,
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
expect(settings).toStrictEqual({ ...projectSettings, framework: null });
|
expect(settings).toStrictEqual({ ...projectSettings, framework: null });
|
||||||
expect((output.print as jest.Mock).mock.calls.length).toBe(5);
|
expect(client.mockOutput.mock.calls.length).toBe(5);
|
||||||
expect((output.print as jest.Mock).mock.calls[0][0]).toMatch(
|
expect(client.mockOutput.mock.calls[0][0]).toMatch(
|
||||||
/No framework detected. Default Project Settings:/
|
/No framework detected. Default Project Settings:/
|
||||||
);
|
);
|
||||||
expect((output.print as jest.Mock).mock.calls[1][0]).toMatch(
|
expect(client.mockOutput.mock.calls[1][0]).toMatch(/Build Command/);
|
||||||
/Build Command/
|
expect(client.mockOutput.mock.calls[2][0]).toMatch(/Development Command/);
|
||||||
);
|
expect(client.mockOutput.mock.calls[3][0]).toMatch(/Install Command/);
|
||||||
expect((output.print as jest.Mock).mock.calls[2][0]).toMatch(
|
expect(client.mockOutput.mock.calls[4][0]).toMatch(/Output Directory/);
|
||||||
/Development Command/
|
|
||||||
);
|
|
||||||
expect((output.print as jest.Mock).mock.calls[3][0]).toMatch(
|
|
||||||
/Install Command/
|
|
||||||
);
|
|
||||||
expect((output.print as jest.Mock).mock.calls[4][0]).toMatch(
|
|
||||||
/Output Directory/
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -99,28 +76,20 @@ describe('editProjectSettings', () => {
|
|||||||
outputDirectory: 'OUTPUT_DIRECTORY',
|
outputDirectory: 'OUTPUT_DIRECTORY',
|
||||||
};
|
};
|
||||||
const settings = await editProjectSettings(
|
const settings = await editProjectSettings(
|
||||||
output,
|
client,
|
||||||
projectSettings,
|
projectSettings,
|
||||||
nextJSFramework,
|
nextJSFramework,
|
||||||
true,
|
true,
|
||||||
null
|
null
|
||||||
);
|
);
|
||||||
expect((output.print as jest.Mock).mock.calls.length).toBe(5);
|
expect(client.mockOutput.mock.calls.length).toBe(5);
|
||||||
expect((output.print as jest.Mock).mock.calls[0][0]).toMatch(
|
expect(client.mockOutput.mock.calls[0][0]).toMatch(
|
||||||
/Auto-detected Project Settings/
|
/Auto-detected Project Settings/
|
||||||
);
|
);
|
||||||
expect((output.print as jest.Mock).mock.calls[1][0]).toMatch(
|
expect(client.mockOutput.mock.calls[1][0]).toMatch(/Build Command/);
|
||||||
/Build Command/
|
expect(client.mockOutput.mock.calls[2][0]).toMatch(/Development Command/);
|
||||||
);
|
expect(client.mockOutput.mock.calls[3][0]).toMatch(/Install Command/);
|
||||||
expect((output.print as jest.Mock).mock.calls[2][0]).toMatch(
|
expect(client.mockOutput.mock.calls[4][0]).toMatch(/Output Directory/);
|
||||||
/Development Command/
|
|
||||||
);
|
|
||||||
expect((output.print as jest.Mock).mock.calls[3][0]).toMatch(
|
|
||||||
/Install Command/
|
|
||||||
);
|
|
||||||
expect((output.print as jest.Mock).mock.calls[4][0]).toMatch(
|
|
||||||
/Output Directory/
|
|
||||||
);
|
|
||||||
expect(settings).toStrictEqual({
|
expect(settings).toStrictEqual({
|
||||||
...projectSettings,
|
...projectSettings,
|
||||||
framework: nextJSFramework.slug,
|
framework: nextJSFramework.slug,
|
||||||
@@ -146,38 +115,28 @@ describe('editProjectSettings', () => {
|
|||||||
outputDirectory: 'OUTPUT_DIRECTORY',
|
outputDirectory: 'OUTPUT_DIRECTORY',
|
||||||
};
|
};
|
||||||
const settings = await editProjectSettings(
|
const settings = await editProjectSettings(
|
||||||
output,
|
client,
|
||||||
projectSettings,
|
projectSettings,
|
||||||
nextJSFramework,
|
nextJSFramework,
|
||||||
true,
|
true,
|
||||||
overrides
|
overrides
|
||||||
);
|
);
|
||||||
expect((output.print as jest.Mock).mock.calls.length).toBe(9);
|
expect(client.mockOutput.mock.calls.length).toBe(9);
|
||||||
expect((output.print as jest.Mock).mock.calls[0][0]).toMatch(
|
expect(client.mockOutput.mock.calls[0][0]).toMatch(
|
||||||
/Local settings detected in vercel.json:/
|
/Local settings detected in vercel.json:/
|
||||||
);
|
);
|
||||||
expect((output.print as jest.Mock).mock.calls[1][0]).toMatch(
|
expect(client.mockOutput.mock.calls[1][0]).toMatch(/Build Command:/);
|
||||||
/Build Command:/
|
expect(client.mockOutput.mock.calls[2][0]).toMatch(/Ignore Command:/);
|
||||||
);
|
expect(client.mockOutput.mock.calls[3][0]).toMatch(
|
||||||
expect((output.print as jest.Mock).mock.calls[2][0]).toMatch(
|
|
||||||
/Ignore Command:/
|
|
||||||
);
|
|
||||||
expect((output.print as jest.Mock).mock.calls[3][0]).toMatch(
|
|
||||||
/Development Command:/
|
/Development Command:/
|
||||||
);
|
);
|
||||||
expect((output.print as jest.Mock).mock.calls[4][0]).toMatch(
|
expect(client.mockOutput.mock.calls[4][0]).toMatch(/Framework:/);
|
||||||
/Framework:/
|
expect(client.mockOutput.mock.calls[5][0]).toMatch(/Install Command:/);
|
||||||
);
|
expect(client.mockOutput.mock.calls[6][0]).toMatch(/Output Directory:/);
|
||||||
expect((output.print as jest.Mock).mock.calls[5][0]).toMatch(
|
expect(client.mockOutput.mock.calls[7][0]).toMatch(
|
||||||
/Install Command:/
|
|
||||||
);
|
|
||||||
expect((output.print as jest.Mock).mock.calls[6][0]).toMatch(
|
|
||||||
/Output Directory:/
|
|
||||||
);
|
|
||||||
expect((output.print as jest.Mock).mock.calls[7][0]).toMatch(
|
|
||||||
/Merging default Project Settings for Svelte. Previously listed overrides are prioritized./
|
/Merging default Project Settings for Svelte. Previously listed overrides are prioritized./
|
||||||
);
|
);
|
||||||
expect((output.print as jest.Mock).mock.calls[8][0]).toMatch(
|
expect(client.mockOutput.mock.calls[8][0]).toMatch(
|
||||||
/Auto-detected Project Settings/
|
/Auto-detected Project Settings/
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -196,38 +155,28 @@ describe('editProjectSettings', () => {
|
|||||||
outputDirectory: 'OUTPUT_DIRECTORY',
|
outputDirectory: 'OUTPUT_DIRECTORY',
|
||||||
};
|
};
|
||||||
const settings = await editProjectSettings(
|
const settings = await editProjectSettings(
|
||||||
output,
|
client,
|
||||||
null,
|
null,
|
||||||
nextJSFramework,
|
nextJSFramework,
|
||||||
true,
|
true,
|
||||||
overrides
|
overrides
|
||||||
);
|
);
|
||||||
expect((output.print as jest.Mock).mock.calls.length).toBe(9);
|
expect(client.mockOutput.mock.calls.length).toBe(9);
|
||||||
expect((output.print as jest.Mock).mock.calls[0][0]).toMatch(
|
expect(client.mockOutput.mock.calls[0][0]).toMatch(
|
||||||
/Local settings detected in vercel.json:/
|
/Local settings detected in vercel.json:/
|
||||||
);
|
);
|
||||||
expect((output.print as jest.Mock).mock.calls[1][0]).toMatch(
|
expect(client.mockOutput.mock.calls[1][0]).toMatch(/Build Command:/);
|
||||||
/Build Command:/
|
expect(client.mockOutput.mock.calls[2][0]).toMatch(/Ignore Command:/);
|
||||||
);
|
expect(client.mockOutput.mock.calls[3][0]).toMatch(
|
||||||
expect((output.print as jest.Mock).mock.calls[2][0]).toMatch(
|
|
||||||
/Ignore Command:/
|
|
||||||
);
|
|
||||||
expect((output.print as jest.Mock).mock.calls[3][0]).toMatch(
|
|
||||||
/Development Command:/
|
/Development Command:/
|
||||||
);
|
);
|
||||||
expect((output.print as jest.Mock).mock.calls[4][0]).toMatch(
|
expect(client.mockOutput.mock.calls[4][0]).toMatch(/Framework:/);
|
||||||
/Framework:/
|
expect(client.mockOutput.mock.calls[5][0]).toMatch(/Install Command:/);
|
||||||
);
|
expect(client.mockOutput.mock.calls[6][0]).toMatch(/Output Directory:/);
|
||||||
expect((output.print as jest.Mock).mock.calls[5][0]).toMatch(
|
expect(client.mockOutput.mock.calls[7][0]).toMatch(
|
||||||
/Install Command:/
|
|
||||||
);
|
|
||||||
expect((output.print as jest.Mock).mock.calls[6][0]).toMatch(
|
|
||||||
/Output Directory:/
|
|
||||||
);
|
|
||||||
expect((output.print as jest.Mock).mock.calls[7][0]).toMatch(
|
|
||||||
/Merging default Project Settings for Svelte. Previously listed overrides are prioritized./
|
/Merging default Project Settings for Svelte. Previously listed overrides are prioritized./
|
||||||
);
|
);
|
||||||
expect((output.print as jest.Mock).mock.calls[8][0]).toMatch(
|
expect(client.mockOutput.mock.calls[8][0]).toMatch(
|
||||||
/Auto-detected Project Settings/
|
/Auto-detected Project Settings/
|
||||||
);
|
);
|
||||||
expect(settings).toStrictEqual(overrides);
|
expect(settings).toStrictEqual(overrides);
|
||||||
@@ -245,38 +194,28 @@ describe('editProjectSettings', () => {
|
|||||||
outputDirectory: 'OUTPUT_DIRECTORY',
|
outputDirectory: 'OUTPUT_DIRECTORY',
|
||||||
};
|
};
|
||||||
const settings = await editProjectSettings(
|
const settings = await editProjectSettings(
|
||||||
output,
|
client,
|
||||||
null,
|
null,
|
||||||
null,
|
null,
|
||||||
true,
|
true,
|
||||||
overrides
|
overrides
|
||||||
);
|
);
|
||||||
expect((output.print as jest.Mock).mock.calls.length).toBe(9);
|
expect(client.mockOutput.mock.calls.length).toBe(9);
|
||||||
expect((output.print as jest.Mock).mock.calls[0][0]).toMatch(
|
expect(client.mockOutput.mock.calls[0][0]).toMatch(
|
||||||
/Local settings detected in vercel.json:/
|
/Local settings detected in vercel.json:/
|
||||||
);
|
);
|
||||||
expect((output.print as jest.Mock).mock.calls[1][0]).toMatch(
|
expect(client.mockOutput.mock.calls[1][0]).toMatch(/Build Command:/);
|
||||||
/Build Command:/
|
expect(client.mockOutput.mock.calls[2][0]).toMatch(/Ignore Command:/);
|
||||||
);
|
expect(client.mockOutput.mock.calls[3][0]).toMatch(
|
||||||
expect((output.print as jest.Mock).mock.calls[2][0]).toMatch(
|
|
||||||
/Ignore Command:/
|
|
||||||
);
|
|
||||||
expect((output.print as jest.Mock).mock.calls[3][0]).toMatch(
|
|
||||||
/Development Command:/
|
/Development Command:/
|
||||||
);
|
);
|
||||||
expect((output.print as jest.Mock).mock.calls[4][0]).toMatch(
|
expect(client.mockOutput.mock.calls[4][0]).toMatch(/Framework:/);
|
||||||
/Framework:/
|
expect(client.mockOutput.mock.calls[5][0]).toMatch(/Install Command:/);
|
||||||
);
|
expect(client.mockOutput.mock.calls[6][0]).toMatch(/Output Directory:/);
|
||||||
expect((output.print as jest.Mock).mock.calls[5][0]).toMatch(
|
expect(client.mockOutput.mock.calls[7][0]).toMatch(
|
||||||
/Install Command:/
|
|
||||||
);
|
|
||||||
expect((output.print as jest.Mock).mock.calls[6][0]).toMatch(
|
|
||||||
/Output Directory:/
|
|
||||||
);
|
|
||||||
expect((output.print as jest.Mock).mock.calls[7][0]).toMatch(
|
|
||||||
/Merging default Project Settings for Svelte. Previously listed overrides are prioritized./
|
/Merging default Project Settings for Svelte. Previously listed overrides are prioritized./
|
||||||
);
|
);
|
||||||
expect((output.print as jest.Mock).mock.calls[8][0]).toMatch(
|
expect(client.mockOutput.mock.calls[8][0]).toMatch(
|
||||||
/Auto-detected Project Settings/
|
/Auto-detected Project Settings/
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vercel/client",
|
"name": "@vercel/client",
|
||||||
"version": "12.0.2",
|
"version": "12.0.3",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
"typings": "dist/index.d.ts",
|
"typings": "dist/index.d.ts",
|
||||||
"homepage": "https://vercel.com",
|
"homepage": "https://vercel.com",
|
||||||
@@ -42,7 +42,7 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vercel/build-utils": "4.2.0",
|
"@vercel/build-utils": "4.2.1",
|
||||||
"@zeit/fetch": "5.2.0",
|
"@zeit/fetch": "5.2.0",
|
||||||
"async-retry": "1.2.3",
|
"async-retry": "1.2.3",
|
||||||
"async-sema": "3.0.0",
|
"async-sema": "3.0.0",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vercel/go",
|
"name": "@vercel/go",
|
||||||
"version": "2.0.2",
|
"version": "2.0.3",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "./dist/index",
|
"main": "./dist/index",
|
||||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/go",
|
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/go",
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
"@types/fs-extra": "^5.0.5",
|
"@types/fs-extra": "^5.0.5",
|
||||||
"@types/node-fetch": "^2.3.0",
|
"@types/node-fetch": "^2.3.0",
|
||||||
"@types/tar": "^4.0.0",
|
"@types/tar": "^4.0.0",
|
||||||
"@vercel/build-utils": "4.2.0",
|
"@vercel/build-utils": "4.2.1",
|
||||||
"@vercel/ncc": "0.24.0",
|
"@vercel/ncc": "0.24.0",
|
||||||
"async-retry": "1.3.1",
|
"async-retry": "1.3.1",
|
||||||
"execa": "^1.0.0",
|
"execa": "^1.0.0",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vercel/next",
|
"name": "@vercel/next",
|
||||||
"version": "3.1.0",
|
"version": "3.1.2",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "./dist/index",
|
"main": "./dist/index",
|
||||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/next-js",
|
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/next-js",
|
||||||
@@ -45,8 +45,8 @@
|
|||||||
"@types/semver": "6.0.0",
|
"@types/semver": "6.0.0",
|
||||||
"@types/text-table": "0.2.1",
|
"@types/text-table": "0.2.1",
|
||||||
"@types/webpack-sources": "3.2.0",
|
"@types/webpack-sources": "3.2.0",
|
||||||
"@vercel/build-utils": "4.2.0",
|
"@vercel/build-utils": "4.2.1",
|
||||||
"@vercel/nft": "0.19.1",
|
"@vercel/nft": "0.20.1",
|
||||||
"@vercel/routing-utils": "1.13.5",
|
"@vercel/routing-utils": "1.13.5",
|
||||||
"async-sema": "3.0.1",
|
"async-sema": "3.0.1",
|
||||||
"buffer-crc32": "0.2.13",
|
"buffer-crc32": "0.2.13",
|
||||||
|
|||||||
@@ -1520,35 +1520,35 @@ export const build: BuildV2 = async ({
|
|||||||
const pageLambdaGroups: Array<LambdaGroup> = [];
|
const pageLambdaGroups: Array<LambdaGroup> = [];
|
||||||
|
|
||||||
if (isSharedLambdas) {
|
if (isSharedLambdas) {
|
||||||
const initialPageLambdaGroups = await getPageLambdaGroups(
|
const initialPageLambdaGroups = await getPageLambdaGroups({
|
||||||
entryPath,
|
entryPath,
|
||||||
config,
|
config,
|
||||||
nonApiPages,
|
pages: nonApiPages,
|
||||||
new Set(),
|
prerenderRoutes: new Set(),
|
||||||
pageTraces,
|
pageTraces,
|
||||||
compressedPages,
|
compressedPages,
|
||||||
tracedPseudoLayer?.pseudoLayer || {},
|
tracedPseudoLayer: tracedPseudoLayer?.pseudoLayer || {},
|
||||||
{ pseudoLayer: {}, pseudoLayerBytes: 0 },
|
initialPseudoLayer: { pseudoLayer: {}, pseudoLayerBytes: 0 },
|
||||||
0,
|
initialPseudoLayerUncompressed: 0,
|
||||||
lambdaCompressedByteLimit,
|
lambdaCompressedByteLimit,
|
||||||
// internal pages are already referenced in traces for serverless
|
// internal pages are already referenced in traces for serverless
|
||||||
// like builds
|
// like builds
|
||||||
[]
|
internalPages: [],
|
||||||
);
|
});
|
||||||
|
|
||||||
const initialApiLambdaGroups = await getPageLambdaGroups(
|
const initialApiLambdaGroups = await getPageLambdaGroups({
|
||||||
entryPath,
|
entryPath,
|
||||||
config,
|
config,
|
||||||
apiPages,
|
pages: apiPages,
|
||||||
new Set(),
|
prerenderRoutes: new Set(),
|
||||||
pageTraces,
|
pageTraces,
|
||||||
compressedPages,
|
compressedPages,
|
||||||
tracedPseudoLayer?.pseudoLayer || {},
|
tracedPseudoLayer: tracedPseudoLayer?.pseudoLayer || {},
|
||||||
{ pseudoLayer: {}, pseudoLayerBytes: 0 },
|
initialPseudoLayer: { pseudoLayer: {}, pseudoLayerBytes: 0 },
|
||||||
0,
|
initialPseudoLayerUncompressed: 0,
|
||||||
lambdaCompressedByteLimit,
|
lambdaCompressedByteLimit,
|
||||||
[]
|
internalPages: [],
|
||||||
);
|
});
|
||||||
|
|
||||||
debug(
|
debug(
|
||||||
JSON.stringify(
|
JSON.stringify(
|
||||||
|
|||||||
@@ -610,34 +610,34 @@ export async function serverBuild({
|
|||||||
|
|
||||||
const pageExtensions = requiredServerFilesManifest.config?.pageExtensions;
|
const pageExtensions = requiredServerFilesManifest.config?.pageExtensions;
|
||||||
|
|
||||||
const pageLambdaGroups = await getPageLambdaGroups(
|
const pageLambdaGroups = await getPageLambdaGroups({
|
||||||
requiredServerFilesManifest.appDir || entryPath,
|
entryPath: requiredServerFilesManifest.appDir || entryPath,
|
||||||
config,
|
config,
|
||||||
nonApiPages,
|
pages: nonApiPages,
|
||||||
prerenderRoutes,
|
prerenderRoutes,
|
||||||
pageTraces,
|
pageTraces,
|
||||||
compressedPages,
|
compressedPages,
|
||||||
tracedPseudoLayer.pseudoLayer,
|
tracedPseudoLayer: tracedPseudoLayer.pseudoLayer,
|
||||||
initialPseudoLayer,
|
initialPseudoLayer,
|
||||||
lambdaCompressedByteLimit,
|
lambdaCompressedByteLimit,
|
||||||
uncompressedInitialSize,
|
initialPseudoLayerUncompressed: uncompressedInitialSize,
|
||||||
internalPages,
|
internalPages,
|
||||||
pageExtensions
|
pageExtensions,
|
||||||
);
|
});
|
||||||
|
|
||||||
const apiLambdaGroups = await getPageLambdaGroups(
|
const apiLambdaGroups = await getPageLambdaGroups({
|
||||||
requiredServerFilesManifest.appDir || entryPath,
|
entryPath: requiredServerFilesManifest.appDir || entryPath,
|
||||||
config,
|
config,
|
||||||
apiPages,
|
pages: apiPages,
|
||||||
prerenderRoutes,
|
prerenderRoutes,
|
||||||
pageTraces,
|
pageTraces,
|
||||||
compressedPages,
|
compressedPages,
|
||||||
tracedPseudoLayer.pseudoLayer,
|
tracedPseudoLayer: tracedPseudoLayer.pseudoLayer,
|
||||||
initialPseudoLayer,
|
initialPseudoLayer,
|
||||||
uncompressedInitialSize,
|
initialPseudoLayerUncompressed: uncompressedInitialSize,
|
||||||
lambdaCompressedByteLimit,
|
lambdaCompressedByteLimit,
|
||||||
internalPages
|
internalPages,
|
||||||
);
|
});
|
||||||
|
|
||||||
debug(
|
debug(
|
||||||
JSON.stringify(
|
JSON.stringify(
|
||||||
|
|||||||
@@ -1275,26 +1275,39 @@ export const MAX_UNCOMPRESSED_LAMBDA_SIZE = 250 * 1000 * 1000; // 250MB
|
|||||||
const LAMBDA_RESERVED_UNCOMPRESSED_SIZE = 2.5 * 1000 * 1000; // 2.5MB
|
const LAMBDA_RESERVED_UNCOMPRESSED_SIZE = 2.5 * 1000 * 1000; // 2.5MB
|
||||||
const LAMBDA_RESERVED_COMPRESSED_SIZE = 250 * 1000; // 250KB
|
const LAMBDA_RESERVED_COMPRESSED_SIZE = 250 * 1000; // 250KB
|
||||||
|
|
||||||
export async function getPageLambdaGroups(
|
export async function getPageLambdaGroups({
|
||||||
entryPath: string,
|
entryPath,
|
||||||
config: Config,
|
config,
|
||||||
pages: string[],
|
pages,
|
||||||
prerenderRoutes: Set<string>,
|
prerenderRoutes,
|
||||||
|
pageTraces,
|
||||||
|
compressedPages,
|
||||||
|
tracedPseudoLayer,
|
||||||
|
initialPseudoLayer,
|
||||||
|
initialPseudoLayerUncompressed,
|
||||||
|
lambdaCompressedByteLimit,
|
||||||
|
internalPages,
|
||||||
|
pageExtensions,
|
||||||
|
}: {
|
||||||
|
entryPath: string;
|
||||||
|
config: Config;
|
||||||
|
pages: string[];
|
||||||
|
prerenderRoutes: Set<string>;
|
||||||
pageTraces: {
|
pageTraces: {
|
||||||
[page: string]: {
|
[page: string]: {
|
||||||
[key: string]: FileFsRef;
|
[key: string]: FileFsRef;
|
||||||
};
|
};
|
||||||
},
|
};
|
||||||
compressedPages: {
|
compressedPages: {
|
||||||
[page: string]: PseudoFile;
|
[page: string]: PseudoFile;
|
||||||
},
|
};
|
||||||
tracedPseudoLayer: PseudoLayer,
|
tracedPseudoLayer: PseudoLayer;
|
||||||
initialPseudoLayer: PseudoLayerResult,
|
initialPseudoLayer: PseudoLayerResult;
|
||||||
initialPseudoLayerUncompressed: number,
|
initialPseudoLayerUncompressed: number;
|
||||||
lambdaCompressedByteLimit: number,
|
lambdaCompressedByteLimit: number;
|
||||||
internalPages: string[],
|
internalPages: string[];
|
||||||
pageExtensions?: string[]
|
pageExtensions?: string[];
|
||||||
) {
|
}) {
|
||||||
const groups: Array<LambdaGroup> = [];
|
const groups: Array<LambdaGroup> = [];
|
||||||
|
|
||||||
for (const page of pages) {
|
for (const page of pages) {
|
||||||
|
|||||||
@@ -105,6 +105,21 @@ it('should build using server build', async () => {
|
|||||||
log.includes('WARNING: Unable to find source file for page')
|
log.includes('WARNING: Unable to find source file for page')
|
||||||
)
|
)
|
||||||
).toBeFalsy();
|
).toBeFalsy();
|
||||||
|
|
||||||
|
const lambdas = new Set();
|
||||||
|
let totalLambdas = 0;
|
||||||
|
|
||||||
|
for (const item of Object.values(output)) {
|
||||||
|
if (item.type === 'Lambda') {
|
||||||
|
totalLambdas += 1;
|
||||||
|
lambdas.add(item);
|
||||||
|
} else if (item.type === 'Prerender') {
|
||||||
|
lambdas.add(item.lambda);
|
||||||
|
totalLambdas += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect(lambdas.size).toBe(5);
|
||||||
|
expect(lambdas.size).toBeLessThan(totalLambdas);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should build custom error lambda correctly', async () => {
|
it('should build custom error lambda correctly', async () => {
|
||||||
@@ -835,3 +850,66 @@ it('Should provide lambda info when limit is hit (uncompressed)', async () => {
|
|||||||
expect(logs).toMatch(/data\.txt/);
|
expect(logs).toMatch(/data\.txt/);
|
||||||
expect(logs).toMatch(/\.next\/server\/pages/);
|
expect(logs).toMatch(/\.next\/server\/pages/);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('Should de-dupe correctly when limit is close (uncompressed)', async () => {
|
||||||
|
const origLog = console.log;
|
||||||
|
const origError = console.error;
|
||||||
|
const caughtLogs = [];
|
||||||
|
|
||||||
|
console.log = function (...args) {
|
||||||
|
caughtLogs.push(args.join(' '));
|
||||||
|
origLog.apply(this, args);
|
||||||
|
};
|
||||||
|
console.error = function (...args) {
|
||||||
|
caughtLogs.push(args.join(' '));
|
||||||
|
origError.apply(this, args);
|
||||||
|
};
|
||||||
|
|
||||||
|
const {
|
||||||
|
buildResult: { output },
|
||||||
|
} = await runBuildLambda(
|
||||||
|
path.join(__dirname, 'test-limit-large-uncompressed-files')
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log = origLog;
|
||||||
|
console.error = origError;
|
||||||
|
|
||||||
|
expect(output['index']).toBeDefined();
|
||||||
|
expect(output['another']).toBeDefined();
|
||||||
|
expect(output['api/hello']).toBeDefined();
|
||||||
|
expect(output['api/hello-1']).toBeDefined();
|
||||||
|
expect(output['api/hello-2']).toBeDefined();
|
||||||
|
expect(output['api/hello-3']).toBeDefined();
|
||||||
|
expect(output['api/hello-4']).toBeDefined();
|
||||||
|
expect(output['_app']).not.toBeDefined();
|
||||||
|
expect(output['_error']).not.toBeDefined();
|
||||||
|
expect(output['_document']).not.toBeDefined();
|
||||||
|
|
||||||
|
expect(output['index'] === output['another']).toBe(true);
|
||||||
|
expect(output['index'] !== output['api/hello']).toBe(true);
|
||||||
|
expect(output['api/hello'] === output['api/hello-1']).toBe(true);
|
||||||
|
expect(output['api/hello'] === output['api/hello-2']).toBe(true);
|
||||||
|
expect(output['api/hello'] === output['api/hello-3']).toBe(true);
|
||||||
|
expect(output['api/hello'] === output['api/hello-4']).toBe(true);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
caughtLogs.some(log =>
|
||||||
|
log.includes('WARNING: Unable to find source file for page')
|
||||||
|
)
|
||||||
|
).toBeFalsy();
|
||||||
|
|
||||||
|
const lambdas = new Set();
|
||||||
|
let totalLambdas = 0;
|
||||||
|
|
||||||
|
for (const item of Object.values(output)) {
|
||||||
|
if (item.type === 'Lambda') {
|
||||||
|
totalLambdas += 1;
|
||||||
|
lambdas.add(item);
|
||||||
|
} else if (item.type === 'Prerender') {
|
||||||
|
lambdas.add(item.lambda);
|
||||||
|
totalLambdas += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
expect(lambdas.size).toBe(2);
|
||||||
|
expect(lambdas.size).toBeLessThan(totalLambdas);
|
||||||
|
});
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
|
||||||
|
// generate 200MB file which will be traced in `/api/hello`
|
||||||
|
fs.writeFileSync('data.txt', Buffer.alloc(200 * 1024 * 1024));
|
||||||
|
|
||||||
|
module.exports = {};
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"name": "test-limit",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"scripts": {
|
||||||
|
"build": "next build"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"next": "canary",
|
||||||
|
"react": "17.0.2",
|
||||||
|
"react-dom": "17.0.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
if (typeof window === 'undefined') {
|
||||||
|
try {
|
||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
fs.readdirSync(path.join(process.cwd(), 'public'));
|
||||||
|
fs.readdirSync(path.join(process.cwd(), 'node_modules/chrome-aws-lambda'));
|
||||||
|
fs.readdirSync(path.join(process.cwd(), 'node_modules/firebase'));
|
||||||
|
} catch (_) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function MyApp({ Component, pageProps }) {
|
||||||
|
return React.createElement(Component, pageProps);
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
export default function Home() {
|
||||||
|
return 'another page';
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getServerSideProps() {
|
||||||
|
require('fs').readFileSync(require('path').join(process.cwd(), 'data.txt'));
|
||||||
|
return {
|
||||||
|
props: {},
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
try {
|
||||||
|
fs.readFileSync(path.join(process.cwd(), 'data.txt'));
|
||||||
|
} catch (_) {
|
||||||
|
/**/
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function handler(req, res) {
|
||||||
|
res.end('hello');
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
try {
|
||||||
|
fs.readFileSync(path.join(process.cwd(), 'data.txt'));
|
||||||
|
} catch (_) {
|
||||||
|
/**/
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function handler(req, res) {
|
||||||
|
res.end('hello');
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
try {
|
||||||
|
fs.readFileSync(path.join(process.cwd(), 'data.txt'));
|
||||||
|
} catch (_) {
|
||||||
|
/**/
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function handler(req, res) {
|
||||||
|
res.end('hello');
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
try {
|
||||||
|
fs.readFileSync(path.join(process.cwd(), 'data.txt'));
|
||||||
|
} catch (_) {
|
||||||
|
/**/
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function handler(req, res) {
|
||||||
|
res.end('hello');
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
import fs from 'fs';
|
||||||
|
import path from 'path';
|
||||||
|
|
||||||
|
try {
|
||||||
|
fs.readFileSync(path.join(process.cwd(), 'data.txt'));
|
||||||
|
} catch (_) {
|
||||||
|
/**/
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function handler(req, res) {
|
||||||
|
res.end('hello');
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
export default function Home() {
|
||||||
|
return 'index page';
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getServerSideProps() {
|
||||||
|
require('fs').readFileSync(require('path').join(process.cwd(), 'data.txt'));
|
||||||
|
return {
|
||||||
|
props: {},
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"version": 2,
|
||||||
|
"builds": [
|
||||||
|
{
|
||||||
|
"src": "package.json",
|
||||||
|
"use": "@vercel/next"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vercel/node",
|
"name": "@vercel/node",
|
||||||
"version": "2.3.0",
|
"version": "2.3.3",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "./dist/index",
|
"main": "./dist/index",
|
||||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/node-js",
|
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/node-js",
|
||||||
@@ -31,11 +31,11 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/node": "*",
|
"@types/node": "*",
|
||||||
"@vercel/build-utils": "4.2.0",
|
"@vercel/build-utils": "4.2.1",
|
||||||
"@vercel/ncc": "0.24.0",
|
|
||||||
"@vercel/node-bridge": "3.0.0",
|
"@vercel/node-bridge": "3.0.0",
|
||||||
"@vercel/static-config": "2.0.1",
|
"@vercel/static-config": "2.0.1",
|
||||||
"edge-runtime": "1.0.1",
|
"edge-runtime": "1.0.1",
|
||||||
|
"esbuild": "0.14.47",
|
||||||
"exit-hook": "2.2.1",
|
"exit-hook": "2.2.1",
|
||||||
"node-fetch": "2.6.1",
|
"node-fetch": "2.6.1",
|
||||||
"ts-node": "8.9.1",
|
"ts-node": "8.9.1",
|
||||||
@@ -52,7 +52,8 @@
|
|||||||
"@types/jest": "27.4.1",
|
"@types/jest": "27.4.1",
|
||||||
"@types/node-fetch": "^2.6.1",
|
"@types/node-fetch": "^2.6.1",
|
||||||
"@types/test-listen": "1.1.0",
|
"@types/test-listen": "1.1.0",
|
||||||
"@vercel/nft": "0.19.1",
|
"@vercel/ncc": "0.24.0",
|
||||||
|
"@vercel/nft": "0.20.1",
|
||||||
"content-type": "1.0.4",
|
"content-type": "1.0.4",
|
||||||
"cookie": "0.4.0",
|
"cookie": "0.4.0",
|
||||||
"etag": "1.8.1",
|
"etag": "1.8.1",
|
||||||
|
|||||||
@@ -79,8 +79,9 @@ import exitHook from 'exit-hook';
|
|||||||
import { EdgeRuntime, Primitives, runServer } from 'edge-runtime';
|
import { EdgeRuntime, Primitives, runServer } from 'edge-runtime';
|
||||||
import { getConfig } from '@vercel/static-config';
|
import { getConfig } from '@vercel/static-config';
|
||||||
import { Project } from 'ts-morph';
|
import { Project } from 'ts-morph';
|
||||||
import ncc from '@vercel/ncc';
|
import esbuild from 'esbuild';
|
||||||
import fetch from 'node-fetch';
|
import fetch from 'node-fetch';
|
||||||
|
import { TextDecoder } from 'util';
|
||||||
|
|
||||||
function logError(error: Error) {
|
function logError(error: Error) {
|
||||||
console.error(error.message);
|
console.error(error.message);
|
||||||
@@ -149,10 +150,22 @@ async function serializeRequest(message: IncomingMessage) {
|
|||||||
|
|
||||||
async function compileUserCode(entrypoint: string) {
|
async function compileUserCode(entrypoint: string) {
|
||||||
try {
|
try {
|
||||||
const buildResult = await ncc(entrypoint, {
|
const result = await esbuild.build({
|
||||||
target: 'es2022',
|
platform: 'node',
|
||||||
|
target: 'node14',
|
||||||
|
sourcemap: 'inline',
|
||||||
|
bundle: true,
|
||||||
|
entryPoints: [entrypoint],
|
||||||
|
write: false, // operate in memory
|
||||||
|
format: 'cjs',
|
||||||
});
|
});
|
||||||
const userCode = buildResult.code;
|
|
||||||
|
const compiledFile = result.outputFiles?.[0];
|
||||||
|
if (!compiledFile) {
|
||||||
|
throw new Error(`Compilation of ${entrypoint} produced no output files.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const userCode = new TextDecoder().decode(compiledFile.contents);
|
||||||
|
|
||||||
return `
|
return `
|
||||||
${userCode};
|
${userCode};
|
||||||
@@ -200,7 +213,8 @@ async function compileUserCode(entrypoint: string) {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
// We can't easily show a meaningful stack trace from ncc -> edge-runtime.
|
// We can't easily show a meaningful stack trace from ncc -> edge-runtime.
|
||||||
// So, stick with just the message for now.
|
// So, stick with just the message for now.
|
||||||
console.log(`Failed to instantiate edge runtime: ${error.message}`);
|
console.error(`Failed to instantiate edge runtime.`);
|
||||||
|
logError(error);
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -231,7 +245,8 @@ async function createEdgeRuntime(userCode: string | undefined) {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
// We can't easily show a meaningful stack trace from ncc -> edge-runtime.
|
// We can't easily show a meaningful stack trace from ncc -> edge-runtime.
|
||||||
// So, stick with just the message for now.
|
// So, stick with just the message for now.
|
||||||
console.log(`Failed to instantiate edge runtime: ${error.message}`);
|
console.error('Failed to instantiate edge runtime.');
|
||||||
|
logError(error);
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vercel/python",
|
"name": "@vercel/python",
|
||||||
"version": "3.0.2",
|
"version": "3.0.3",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/python",
|
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/python",
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/execa": "^0.9.0",
|
"@types/execa": "^0.9.0",
|
||||||
"@types/jest": "27.4.1",
|
"@types/jest": "27.4.1",
|
||||||
"@vercel/build-utils": "4.2.0",
|
"@vercel/build-utils": "4.2.1",
|
||||||
"@vercel/ncc": "0.24.0",
|
"@vercel/ncc": "0.24.0",
|
||||||
"execa": "^1.0.0",
|
"execa": "^1.0.0",
|
||||||
"typescript": "4.3.4"
|
"typescript": "4.3.4"
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vercel/redwood",
|
"name": "@vercel/redwood",
|
||||||
"version": "1.0.2",
|
"version": "1.0.4",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"homepage": "https://vercel.com/docs",
|
"homepage": "https://vercel.com/docs",
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
"prepublishOnly": "node build.js"
|
"prepublishOnly": "node build.js"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vercel/nft": "0.19.1",
|
"@vercel/nft": "0.20.1",
|
||||||
"@vercel/routing-utils": "1.13.5",
|
"@vercel/routing-utils": "1.13.5",
|
||||||
"semver": "6.1.1"
|
"semver": "6.1.1"
|
||||||
},
|
},
|
||||||
@@ -28,6 +28,6 @@
|
|||||||
"@types/aws-lambda": "8.10.19",
|
"@types/aws-lambda": "8.10.19",
|
||||||
"@types/node": "*",
|
"@types/node": "*",
|
||||||
"@types/semver": "6.0.0",
|
"@types/semver": "6.0.0",
|
||||||
"@vercel/build-utils": "4.2.0"
|
"@vercel/build-utils": "4.2.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vercel/remix",
|
"name": "@vercel/remix",
|
||||||
"version": "1.0.2",
|
"version": "1.0.4",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"homepage": "https://vercel.com/docs",
|
"homepage": "https://vercel.com/docs",
|
||||||
@@ -21,12 +21,12 @@
|
|||||||
"default-server.js"
|
"default-server.js"
|
||||||
],
|
],
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@vercel/nft": "0.19.1"
|
"@vercel/nft": "0.20.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "27.5.1",
|
"@types/jest": "27.5.1",
|
||||||
"@types/node": "*",
|
"@types/node": "*",
|
||||||
"@vercel/build-utils": "4.2.0",
|
"@vercel/build-utils": "4.2.1",
|
||||||
"typescript": "4.6.4"
|
"typescript": "4.6.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "@vercel/ruby",
|
"name": "@vercel/ruby",
|
||||||
"author": "Nathan Cahill <nathan@nathancahill.com>",
|
"author": "Nathan Cahill <nathan@nathancahill.com>",
|
||||||
"version": "1.3.10",
|
"version": "1.3.11",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "./dist/index",
|
"main": "./dist/index",
|
||||||
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/ruby",
|
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/ruby",
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/fs-extra": "8.0.0",
|
"@types/fs-extra": "8.0.0",
|
||||||
"@types/semver": "6.0.0",
|
"@types/semver": "6.0.0",
|
||||||
"@vercel/build-utils": "4.2.0",
|
"@vercel/build-utils": "4.2.1",
|
||||||
"@vercel/ncc": "0.24.0",
|
"@vercel/ncc": "0.24.0",
|
||||||
"execa": "2.0.4",
|
"execa": "2.0.4",
|
||||||
"fs-extra": "^7.0.1",
|
"fs-extra": "^7.0.1",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@vercel/static-build",
|
"name": "@vercel/static-build",
|
||||||
"version": "1.0.2",
|
"version": "1.0.3",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"main": "./dist/index",
|
"main": "./dist/index",
|
||||||
"homepage": "https://vercel.com/docs/build-step",
|
"homepage": "https://vercel.com/docs/build-step",
|
||||||
@@ -37,7 +37,7 @@
|
|||||||
"@types/ms": "0.7.31",
|
"@types/ms": "0.7.31",
|
||||||
"@types/node-fetch": "2.5.4",
|
"@types/node-fetch": "2.5.4",
|
||||||
"@types/promise-timeout": "1.3.0",
|
"@types/promise-timeout": "1.3.0",
|
||||||
"@vercel/build-utils": "4.2.0",
|
"@vercel/build-utils": "4.2.1",
|
||||||
"@vercel/frameworks": "1.0.2",
|
"@vercel/frameworks": "1.0.2",
|
||||||
"@vercel/ncc": "0.24.0",
|
"@vercel/ncc": "0.24.0",
|
||||||
"@vercel/routing-utils": "1.13.5",
|
"@vercel/routing-utils": "1.13.5",
|
||||||
|
|||||||
69
yarn.lock
69
yarn.lock
@@ -3042,10 +3042,10 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@vercel/ncc/-/ncc-0.24.0.tgz#a2e8783a185caa99b5d8961a57dfc9665de16296"
|
resolved "https://registry.yarnpkg.com/@vercel/ncc/-/ncc-0.24.0.tgz#a2e8783a185caa99b5d8961a57dfc9665de16296"
|
||||||
integrity sha512-crqItMcIwCkvdXY/V3/TzrHJQx6nbIaRqE1cOopJhgGX6izvNov40SmD//nS5flfEvdK54YGjwVVq+zG6crjOg==
|
integrity sha512-crqItMcIwCkvdXY/V3/TzrHJQx6nbIaRqE1cOopJhgGX6izvNov40SmD//nS5flfEvdK54YGjwVVq+zG6crjOg==
|
||||||
|
|
||||||
"@vercel/nft@0.19.1":
|
"@vercel/nft@0.20.1":
|
||||||
version "0.19.1"
|
version "0.20.1"
|
||||||
resolved "https://registry.yarnpkg.com/@vercel/nft/-/nft-0.19.1.tgz#dcd3c20d7ef14d2050244e7d5edcfecc7303dd46"
|
resolved "https://registry.yarnpkg.com/@vercel/nft/-/nft-0.20.1.tgz#41e559af189405c526ac1f6709773bc99995b95b"
|
||||||
integrity sha512-klR5oN7S3WJsZz0r6Xsq7o8YlFEyU3/00VmlpZzIPVFzKfbcEjXo/sVR5lQBUqNKuOzhcbxaFtzW9aOyHjmPYA==
|
integrity sha512-hSLcr64KHOkcNiTAlv154K4p4faEFBwYIi2eIgu1QCDhB1qyQYvFuEhtw3eaapNjA4/7x/2jcclfCAjILua/ag==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@mapbox/node-pre-gyp" "^1.0.5"
|
"@mapbox/node-pre-gyp" "^1.0.5"
|
||||||
acorn "^8.6.0"
|
acorn "^8.6.0"
|
||||||
@@ -3055,7 +3055,6 @@
|
|||||||
graceful-fs "^4.2.9"
|
graceful-fs "^4.2.9"
|
||||||
micromatch "^4.0.2"
|
micromatch "^4.0.2"
|
||||||
node-gyp-build "^4.2.2"
|
node-gyp-build "^4.2.2"
|
||||||
node-pre-gyp "^0.13.0"
|
|
||||||
resolve-from "^5.0.0"
|
resolve-from "^5.0.0"
|
||||||
rollup-pluginutils "^2.8.2"
|
rollup-pluginutils "^2.8.2"
|
||||||
|
|
||||||
@@ -4986,7 +4985,7 @@ debug@4, debug@4.1.1, debug@^4.1.0, debug@^4.1.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
ms "^2.1.1"
|
ms "^2.1.1"
|
||||||
|
|
||||||
debug@^3.0.0, debug@^3.1.0, debug@^3.2.6:
|
debug@^3.0.0, debug@^3.1.0:
|
||||||
version "3.2.6"
|
version "3.2.6"
|
||||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
|
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
|
||||||
integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
|
integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
|
||||||
@@ -5175,7 +5174,7 @@ detect-indent@^5.0.0:
|
|||||||
resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d"
|
resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-5.0.0.tgz#3871cc0a6a002e8c3e5b3cf7f336264675f06b9d"
|
||||||
integrity sha1-OHHMCmoALow+Wzz38zYmRnXwa50=
|
integrity sha1-OHHMCmoALow+Wzz38zYmRnXwa50=
|
||||||
|
|
||||||
detect-libc@^1.0.2, detect-libc@^1.0.3:
|
detect-libc@^1.0.3:
|
||||||
version "1.0.3"
|
version "1.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
|
resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
|
||||||
integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=
|
integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=
|
||||||
@@ -5607,12 +5606,7 @@ esbuild@0.12.22:
|
|||||||
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.12.22.tgz#6031a1257b8d0307d306bed673b79c3668607f51"
|
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.12.22.tgz#6031a1257b8d0307d306bed673b79c3668607f51"
|
||||||
integrity sha512-yWCr9RoFehpqoe/+MwZXJpYOEIt7KOEvNnjIeMZpMSyQt+KCBASM3y7yViiN5dJRphf1wGdUz1+M4rTtWd/ulA==
|
integrity sha512-yWCr9RoFehpqoe/+MwZXJpYOEIt7KOEvNnjIeMZpMSyQt+KCBASM3y7yViiN5dJRphf1wGdUz1+M4rTtWd/ulA==
|
||||||
|
|
||||||
esbuild@^0.11.20:
|
esbuild@0.14.47, esbuild@^0.14.25:
|
||||||
version "0.11.23"
|
|
||||||
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.11.23.tgz#c42534f632e165120671d64db67883634333b4b8"
|
|
||||||
integrity sha512-iaiZZ9vUF5wJV8ob1tl+5aJTrwDczlvGP0JoMmnpC2B0ppiMCu8n8gmy5ZTGl5bcG081XBVn+U+jP+mPFm5T5Q==
|
|
||||||
|
|
||||||
esbuild@^0.14.25:
|
|
||||||
version "0.14.47"
|
version "0.14.47"
|
||||||
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.47.tgz#0d6415f6bd8eb9e73a58f7f9ae04c5276cda0e4d"
|
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.14.47.tgz#0d6415f6bd8eb9e73a58f7f9ae04c5276cda0e4d"
|
||||||
integrity sha512-wI4ZiIfFxpkuxB8ju4MHrGwGLyp1+awEHAHVpx6w7a+1pmYIq8T9FGEVVwFo0iFierDoMj++Xq69GXWYn2EiwA==
|
integrity sha512-wI4ZiIfFxpkuxB8ju4MHrGwGLyp1+awEHAHVpx6w7a+1pmYIq8T9FGEVVwFo0iFierDoMj++Xq69GXWYn2EiwA==
|
||||||
@@ -5638,6 +5632,11 @@ esbuild@^0.14.25:
|
|||||||
esbuild-windows-64 "0.14.47"
|
esbuild-windows-64 "0.14.47"
|
||||||
esbuild-windows-arm64 "0.14.47"
|
esbuild-windows-arm64 "0.14.47"
|
||||||
|
|
||||||
|
esbuild@^0.11.20:
|
||||||
|
version "0.11.23"
|
||||||
|
resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.11.23.tgz#c42534f632e165120671d64db67883634333b4b8"
|
||||||
|
integrity sha512-iaiZZ9vUF5wJV8ob1tl+5aJTrwDczlvGP0JoMmnpC2B0ppiMCu8n8gmy5ZTGl5bcG081XBVn+U+jP+mPFm5T5Q==
|
||||||
|
|
||||||
escalade@^3.1.1:
|
escalade@^3.1.1:
|
||||||
version "3.1.1"
|
version "3.1.1"
|
||||||
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
|
resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
|
||||||
@@ -7077,7 +7076,7 @@ husky@7.0.4:
|
|||||||
resolved "https://registry.yarnpkg.com/husky/-/husky-7.0.4.tgz#242048245dc49c8fb1bf0cc7cfb98dd722531535"
|
resolved "https://registry.yarnpkg.com/husky/-/husky-7.0.4.tgz#242048245dc49c8fb1bf0cc7cfb98dd722531535"
|
||||||
integrity sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ==
|
integrity sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ==
|
||||||
|
|
||||||
iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@^0.4.4, iconv-lite@~0.4.13:
|
iconv-lite@0.4.24, iconv-lite@^0.4.24, iconv-lite@~0.4.13:
|
||||||
version "0.4.24"
|
version "0.4.24"
|
||||||
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
|
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.24.tgz#2022b4b25fbddc21d2f524974a474aafe733908b"
|
||||||
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
|
integrity sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==
|
||||||
@@ -9328,15 +9327,6 @@ ndjson@2.0.0:
|
|||||||
split2 "^3.0.0"
|
split2 "^3.0.0"
|
||||||
through2 "^4.0.0"
|
through2 "^4.0.0"
|
||||||
|
|
||||||
needle@^2.2.1:
|
|
||||||
version "2.5.2"
|
|
||||||
resolved "https://registry.yarnpkg.com/needle/-/needle-2.5.2.tgz#cf1a8fce382b5a280108bba90a14993c00e4010a"
|
|
||||||
integrity sha512-LbRIwS9BfkPvNwNHlsA41Q29kL2L/6VaOJ0qisM5lLWsTV3nP15abO5ITL6L81zqFhzjRKDAYjpcBcwM0AVvLQ==
|
|
||||||
dependencies:
|
|
||||||
debug "^3.2.6"
|
|
||||||
iconv-lite "^0.4.4"
|
|
||||||
sax "^1.2.4"
|
|
||||||
|
|
||||||
negotiator@0.6.2:
|
negotiator@0.6.2:
|
||||||
version "0.6.2"
|
version "0.6.2"
|
||||||
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb"
|
resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.2.tgz#feacf7ccf525a77ae9634436a64883ffeca346fb"
|
||||||
@@ -9403,22 +9393,6 @@ node-int64@^0.4.0:
|
|||||||
resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"
|
resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b"
|
||||||
integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=
|
integrity sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=
|
||||||
|
|
||||||
node-pre-gyp@^0.13.0:
|
|
||||||
version "0.13.0"
|
|
||||||
resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.13.0.tgz#df9ab7b68dd6498137717838e4f92a33fc9daa42"
|
|
||||||
integrity sha512-Md1D3xnEne8b/HGVQkZZwV27WUi1ZRuZBij24TNaZwUPU3ZAFtvT6xxJGaUVillfmMKnn5oD1HoGsp2Ftik7SQ==
|
|
||||||
dependencies:
|
|
||||||
detect-libc "^1.0.2"
|
|
||||||
mkdirp "^0.5.1"
|
|
||||||
needle "^2.2.1"
|
|
||||||
nopt "^4.0.1"
|
|
||||||
npm-packlist "^1.1.6"
|
|
||||||
npmlog "^4.0.2"
|
|
||||||
rc "^1.2.7"
|
|
||||||
rimraf "^2.6.1"
|
|
||||||
semver "^5.3.0"
|
|
||||||
tar "^4"
|
|
||||||
|
|
||||||
node-releases@^2.0.3:
|
node-releases@^2.0.3:
|
||||||
version "2.0.3"
|
version "2.0.3"
|
||||||
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.3.tgz#225ee7488e4a5e636da8da52854844f9d716ca96"
|
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.3.tgz#225ee7488e4a5e636da8da52854844f9d716ca96"
|
||||||
@@ -9510,7 +9484,7 @@ npm-package-arg@6.1.0:
|
|||||||
semver "^5.6.0"
|
semver "^5.6.0"
|
||||||
validate-npm-package-name "^3.0.0"
|
validate-npm-package-name "^3.0.0"
|
||||||
|
|
||||||
npm-packlist@^1.1.6, npm-packlist@^1.4.4:
|
npm-packlist@^1.4.4:
|
||||||
version "1.4.8"
|
version "1.4.8"
|
||||||
resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.8.tgz#56ee6cc135b9f98ad3d51c1c95da22bbb9b2ef3e"
|
resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.4.8.tgz#56ee6cc135b9f98ad3d51c1c95da22bbb9b2ef3e"
|
||||||
integrity sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==
|
integrity sha512-5+AZgwru5IevF5ZdnFglB5wNlHG1AOOuw28WhUq8/8emhBmLv6jX5by4WJCh7lW0uSYZYS6DXqIsyZVIXRZU9A==
|
||||||
@@ -9549,7 +9523,7 @@ npm-run-path@^4.0.0, npm-run-path@^4.0.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
path-key "^3.0.0"
|
path-key "^3.0.0"
|
||||||
|
|
||||||
npmlog@^4.0.2, npmlog@^4.1.2:
|
npmlog@^4.1.2:
|
||||||
version "4.1.2"
|
version "4.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b"
|
resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b"
|
||||||
integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==
|
integrity sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==
|
||||||
@@ -10532,7 +10506,7 @@ rc9@1.2.0:
|
|||||||
destr "^1.0.0"
|
destr "^1.0.0"
|
||||||
flat "^5.0.0"
|
flat "^5.0.0"
|
||||||
|
|
||||||
rc@^1.2.7, rc@^1.2.8:
|
rc@^1.2.8:
|
||||||
version "1.2.8"
|
version "1.2.8"
|
||||||
resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
|
resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
|
||||||
integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==
|
integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==
|
||||||
@@ -10972,7 +10946,7 @@ rimraf@3.0.2, rimraf@^3.0.0, rimraf@^3.0.2:
|
|||||||
dependencies:
|
dependencies:
|
||||||
glob "^7.1.3"
|
glob "^7.1.3"
|
||||||
|
|
||||||
rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2, rimraf@^2.6.3:
|
rimraf@^2.5.4, rimraf@^2.6.2, rimraf@^2.6.3:
|
||||||
version "2.7.1"
|
version "2.7.1"
|
||||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
|
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
|
||||||
integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
|
integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
|
||||||
@@ -11039,11 +11013,6 @@ safe-regex@^1.1.0:
|
|||||||
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a"
|
||||||
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
integrity sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==
|
||||||
|
|
||||||
sax@^1.2.4:
|
|
||||||
version "1.2.4"
|
|
||||||
resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9"
|
|
||||||
integrity sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==
|
|
||||||
|
|
||||||
semver-compare@^1.0.0:
|
semver-compare@^1.0.0:
|
||||||
version "1.0.0"
|
version "1.0.0"
|
||||||
resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc"
|
resolved "https://registry.yarnpkg.com/semver-compare/-/semver-compare-1.0.0.tgz#0dee216a1c941ab37e9efb1788f6afc5ff5537fc"
|
||||||
@@ -11063,7 +11032,7 @@ semver-diff@^3.1.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
semver "^6.3.0"
|
semver "^6.3.0"
|
||||||
|
|
||||||
"semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", semver@^5.0.3, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0, semver@^5.7.1:
|
"semver@2 || 3 || 4 || 5", "semver@2.x || 3.x || 4 || 5", semver@^5.0.3, semver@^5.4.1, semver@^5.5.0, semver@^5.5.1, semver@^5.6.0, semver@^5.7.0, semver@^5.7.1:
|
||||||
version "5.7.1"
|
version "5.7.1"
|
||||||
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
|
resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
|
||||||
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
|
integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
|
||||||
@@ -11864,7 +11833,7 @@ tar@4.4.8:
|
|||||||
safe-buffer "^5.1.2"
|
safe-buffer "^5.1.2"
|
||||||
yallist "^3.0.2"
|
yallist "^3.0.2"
|
||||||
|
|
||||||
tar@^4, tar@^4.4.10, tar@^4.4.12, tar@^4.4.8:
|
tar@^4.4.10, tar@^4.4.12, tar@^4.4.8:
|
||||||
version "4.4.13"
|
version "4.4.13"
|
||||||
resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525"
|
resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.13.tgz#43b364bc52888d555298637b10d60790254ab525"
|
||||||
integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==
|
integrity sha512-w2VwSrBoHa5BsSyH+KxEqeQBAllHhccyMFVHtGtdMpF4W7IRWfZjFiQceJPChOeTsSDVUpER2T8FA93pr0L+QA==
|
||||||
|
|||||||
Reference in New Issue
Block a user