Compare commits

...

10 Commits

Author SHA1 Message Date
Jared Palmer
e0771def26 Symlink / hardlink benchmark code 2021-11-18 10:56:23 -05:00
Miroslav Simulcik
c4fc060030 [cli] Fix spinner output outside of TTY (#7017)
* Fix spinner output outside of TTY

* Use console.log

* Fix tests

* Revert "Fix tests"

This reverts commit 44383eea2dc3bb699d943079d77961ed86fe65d6.

* Revert "Use console.log"

This reverts commit 251bd1d624532e9ecfb4aee5b31538aa4ba740ef.
2021-11-17 14:04:59 +01:00
Steven
3fa08bf64f [cli] Fix update command to favor npm (#7018) 2021-11-16 16:07:31 -05:00
Steven
43056bde1f Publish Canary
- vercel@23.1.3-canary.33
2021-11-15 18:07:17 -05:00
Steven
a49966b9b4 [cli] Change vc build to use stdout (#7005) 2021-11-15 18:06:48 -05:00
Steven
7f55de71bb Publish Canary
- vercel@23.1.3-canary.32
 - @vercel/go@1.2.4-canary.4
 - vercel-plugin-go@1.0.0-canary.3
2021-11-15 13:37:04 -05:00
Steven
db8e36e04c [go] Add support for version 1.17 (#7002)
* Support more Go versions

Co-authored-by: Stefan M <StefMa@users.noreply.github.com>
2021-11-15 13:36:26 -05:00
Andy Bitz
82924bb5c4 Publish Canary
- vercel@23.1.3-canary.31
 - vercel-plugin-node@1.12.2-canary.9
2021-11-15 14:11:55 +01:00
Andy
18b5fac93e [vercel-plugin-node] Use .nft.json files instead of directories. (#6988)
* Ignore install step if package.json does not exist in entrypoint directory

* [plugin-node] Use `.nft.json` files

* Bump @vercel/fun

* Update package.json

* Remove package

* Remove import

* Update paths

* Revert "Update paths"

This reverts commit fa304e90381f475c64b2333402dca489813522da.

* Update path for windows

* Update handler path
2021-11-15 14:08:49 +01:00
Miroslav Simulcik
a6012e600b [cli] Fix updating of gitignore in vercel link (#6986)
* Fix updating of gitignore in link

* Fix modification of gitignore file during linking

* Fix empty file case
2021-11-12 17:11:21 +01:00
19 changed files with 280 additions and 141 deletions

1
.gitignore vendored
View File

@@ -27,3 +27,4 @@ test/lib/deployment/failed-page.txt
/public
__pycache__
.vercel
.output

View File

@@ -1,6 +1,6 @@
{
"name": "vercel",
"version": "23.1.3-canary.30",
"version": "23.1.3-canary.33",
"preferGlobal": true,
"license": "Apache-2.0",
"description": "The command-line interface for Vercel",
@@ -44,13 +44,13 @@
},
"dependencies": {
"@vercel/build-utils": "2.12.3-canary.18",
"@vercel/go": "1.2.4-canary.3",
"@vercel/go": "1.2.4-canary.4",
"@vercel/node": "1.12.2-canary.6",
"@vercel/python": "2.0.6-canary.5",
"@vercel/ruby": "1.2.8-canary.4",
"update-notifier": "4.1.0",
"vercel-plugin-middleware": "0.0.0-canary.7",
"vercel-plugin-node": "1.12.2-canary.8"
"vercel-plugin-node": "1.12.2-canary.9"
},
"devDependencies": {
"@next/env": "11.1.2",

View File

@@ -169,15 +169,15 @@ export default async function main(client: Client) {
const buildState = { ...project.settings };
client.output.log(`Retrieved Project Settings:`);
client.output.print(
chalk.dim(` - ${chalk.bold(`Framework Preset:`)} ${framework.name}\n`)
console.log(`Retrieved Project Settings:`);
console.log(
chalk.dim(` - ${chalk.bold(`Framework Preset:`)} ${framework.name}`)
);
for (let field of fields) {
const defaults = (framework.settings as any)[field.value];
if (defaults) {
client.output.print(
console.log(
chalk.dim(
` - ${chalk.bold(`${field.name}:`)} ${`${
project.settings[field.value]
@@ -185,7 +185,7 @@ export default async function main(client: Client) {
: isSettingValue(defaults)
? defaults.value
: chalk.italic(`${defaults.placeholder}`)
}`}\n`
}`}`
)
);
}
@@ -201,14 +201,14 @@ export default async function main(client: Client) {
}
if (loadedEnvFiles.length > 0) {
client.output.log(
console.log(
`Loaded Environment Variables from ${loadedEnvFiles.length} ${pluralize(
'file',
loadedEnvFiles.length
)}:`
);
for (let envFile of loadedEnvFiles) {
client.output.print(chalk.dim(` - ${envFile.path}\n`));
console.log(chalk.dim(` - ${envFile.path}`));
}
}
@@ -239,7 +239,7 @@ export default async function main(client: Client) {
};
if (plugins?.pluginCount && plugins?.pluginCount > 0) {
client.output.log(
console.log(
`Loaded ${plugins.pluginCount} CLI ${pluralize(
'Plugin',
plugins.pluginCount
@@ -247,7 +247,7 @@ export default async function main(client: Client) {
);
// preBuild Plugins
if (plugins.preBuildPlugins.length > 0) {
client.output.log(
console.log(
`Running ${plugins.pluginCount} CLI ${pluralize(
'Plugin',
plugins.pluginCount
@@ -286,7 +286,7 @@ export default async function main(client: Client) {
fs.removeSync(join(cwd, OUTPUT_DIR));
if (typeof buildState.buildCommand === 'string') {
client.output.log(`Running Build Command: ${cmd(buildState.buildCommand)}`);
console.log(`Running Build Command: ${cmd(buildState.buildCommand)}`);
await execCommand(buildState.buildCommand, {
...spawnOpts,
// Yarn v2 PnP mode may be activated, so force
@@ -352,7 +352,7 @@ export default async function main(client: Client) {
)
);
client.output.stopSpinner();
client.output.log(
console.log(
`Copied ${files.length.toLocaleString()} files from ${param(
distDir
)} to ${param(outputDir)} ${copyStamp()}`
@@ -572,49 +572,49 @@ export default async function main(client: Client) {
}
// Build Plugins
if (plugins?.buildPlugins && plugins.buildPlugins.length > 0) {
client.output.log(
`Running ${plugins.pluginCount} CLI ${pluralize(
'Plugin',
plugins.pluginCount
)} after Build Command:`
);
for (let item of plugins.buildPlugins) {
const { name, plugin, color } = item;
if (typeof plugin.build === 'function') {
const pluginStamp = stamp();
const fullName = name + '.build';
const prefix = chalk.gray(' > ') + color(fullName + ':');
client.output.debug(`Running ${fullName}:`);
try {
console.log = (...args: any[]) => prefixedLog(prefix, args, origLog);
console.error = (...args: any[]) =>
prefixedLog(prefix, args, origErr);
await plugin.build({
workPath: cwd,
});
client.output.debug(
`Completed ${fullName} ${chalk.dim(`${pluginStamp()}`)}`
);
} catch (error) {
client.output.error(`${prefix} failed`);
handleError(error, { debug });
return 1;
} finally {
console.log = origLog;
console.error = origLog;
}
}
}
}
// if (plugins?.buildPlugins && plugins.buildPlugins.length > 0) {
// console.log(
// `Running ${plugins.pluginCount} CLI ${pluralize(
// 'Plugin',
// plugins.pluginCount
// )} after Build Command:`
// );
// for (let item of plugins.buildPlugins) {
// const { name, plugin, color } = item;
// if (typeof plugin.build === 'function') {
// const pluginStamp = stamp();
// const fullName = name + '.build';
// const prefix = chalk.gray(' > ') + color(fullName + ':');
// client.output.debug(`Running ${fullName}:`);
// try {
// console.log = (...args: any[]) => prefixedLog(prefix, args, origLog);
// console.error = (...args: any[]) =>
// prefixedLog(prefix, args, origErr);
// await plugin.build({
// workPath: cwd,
// });
// client.output.debug(
// `Completed ${fullName} ${chalk.dim(`${pluginStamp()}`)}`
// );
// } catch (error) {
// client.output.error(`${prefix} failed`);
// handleError(error, { debug });
// return 1;
// } finally {
// console.log = origLog;
// console.error = origLog;
// }
// }
// }
// }
client.output.print(
console.log(
`${prependEmoji(
`Build Completed in ${chalk.bold(OUTPUT_DIR)} ${chalk.gray(
buildStamp()
)}`,
emoji('success')
)}\n`
)}`
);
return 0;
@@ -660,16 +660,22 @@ export async function runPackageJsonScript(
}
}
client.output.log(`Running Build Command: ${cmd(opts.prettyCommand)}\n`);
console.log(`Running Build Command: ${cmd(opts.prettyCommand)}\n`);
await spawnAsync(cliType, ['run', scriptName], opts);
client.output.print('\n'); // give it some room
console.log(); // give it some room
client.output.debug(`Script complete [${Date.now() - runScriptTime}ms]`);
return true;
}
async function linkOrCopy(existingPath: string, newPath: string) {
try {
await fs.createLink(existingPath, newPath);
if (newPath.endsWith('.json')) {
await fs.copy(existingPath, newPath, {
overwrite: true,
});
} else {
await fs.createSymlink(existingPath, newPath, 'file');
}
} catch (err: any) {
// eslint-disable-line
// If a hard link to the same file already exists
@@ -678,7 +684,9 @@ async function linkOrCopy(existingPath: string, newPath: string) {
// In some VERY rare cases (1 in a thousand), hard-link creation fails on Windows.
// In that case, we just fall back to copying.
// This issue is reproducible with "pnpm add @material-ui/icons@4.9.1"
await fs.copyFile(existingPath, newPath);
await fs.copy(existingPath, newPath, {
overwrite: true,
});
}
}

View File

@@ -160,24 +160,26 @@ const main = async () => {
// * a path to deploy (as in: `vercel path/`)
// * a subcommand (as in: `vercel ls`)
const targetOrSubcommand = argv._[2];
const isBuildOrDev =
targetOrSubcommand === 'build' || targetOrSubcommand === 'dev';
output.print(
`${chalk.grey(
`${getTitleName()} CLI ${pkg.version}${
targetOrSubcommand === 'dev'
? ' dev (beta)'
: targetOrSubcommand === 'build'
? ' build (beta)'
: ''
}${
isCanary ||
targetOrSubcommand === 'dev' ||
targetOrSubcommand === 'build'
? ' — https://vercel.com/feedback'
: ''
}`
)}\n`
);
if (isBuildOrDev) {
console.log(
`${chalk.grey(
`${getTitleName()} CLI ${
pkg.version
} ${targetOrSubcommand} (beta) — https://vercel.com/feedback`
)}`
);
} else {
output.print(
`${chalk.grey(
`${getTitleName()} CLI ${pkg.version}${
isCanary ? ' — https://vercel.com/feedback' : ''
}`
)}\n`
);
}
// Handle `--version` directly
if (!targetOrSubcommand && argv['--version']) {

View File

@@ -1,11 +1,9 @@
import { Stats } from 'fs';
import { sep, dirname, join, resolve } from 'path';
import { readJSON, lstat, readlink, readFile, realpath } from 'fs-extra';
import { lstat, readlink, readFile, realpath } from 'fs-extra';
import { isCanary } from './is-canary';
import { getPkgName } from './pkg-name';
// `npm` tacks a bunch of extra properties on the `package.json` file,
// so check for one of them to determine yarn vs. npm.
async function isYarn(): Promise<boolean> {
let s: Stats;
let binPath = process.argv[1];
@@ -20,8 +18,12 @@ async function isYarn(): Promise<boolean> {
}
}
const pkgPath = join(dirname(binPath), '..', 'package.json');
const pkg = await readJSON(pkgPath).catch(() => ({}));
return !('_id' in pkg);
/*
* Generally, pkgPath looks like:
* "/Users/username/.config/yarn/global/node_modules/vercel/package.json"
* "/usr/local/share/.config/yarn/global/node_modules/vercel/package.json"
*/
return pkgPath.includes(join('yarn', 'global'));
}
async function getConfigPrefix() {

View File

@@ -125,10 +125,14 @@ export class Output {
this.debug(`Spinner invoked (${message}) with a ${delay}ms delay`);
return;
}
if (this._spinner) {
this._spinner.text = message;
if (this.isTTY) {
if (this._spinner) {
this._spinner.text = message;
} else {
this._spinner = wait(message, delay);
}
} else {
this._spinner = wait(message, delay);
this.print(`${message}\n`);
}
};

View File

@@ -244,20 +244,27 @@ export async function linkFolderToProject(
try {
const gitIgnorePath = join(path, '.gitignore');
const gitIgnore = await readFile(gitIgnorePath, 'utf8').catch(() => null);
const EOL = gitIgnore && gitIgnore.includes('\r\n') ? '\r\n' : os.EOL;
let gitIgnore =
(await readFile(gitIgnorePath, 'utf8').catch(() => null)) ?? '';
const EOL = gitIgnore.includes('\r\n') ? '\r\n' : os.EOL;
let contentModified = false;
if (
!gitIgnore ||
!gitIgnore.split(EOL).includes(VERCEL_DIR) ||
!gitIgnore.split(EOL).includes(VERCEL_OUTPUT_DIR)
) {
await writeFile(
gitIgnorePath,
gitIgnore
? `${gitIgnore}${EOL}${VERCEL_DIR}${EOL}${VERCEL_OUTPUT_DIR}${EOL}`
: `${VERCEL_DIR}${EOL}${VERCEL_OUTPUT_DIR}${EOL}`
);
if (!gitIgnore.split(EOL).includes(VERCEL_DIR)) {
gitIgnore += `${
gitIgnore.endsWith(EOL) || gitIgnore.length === 0 ? '' : EOL
}${VERCEL_DIR}${EOL}`;
contentModified = true;
}
if (!gitIgnore.split(EOL).includes(VERCEL_OUTPUT_DIR)) {
gitIgnore += `${
gitIgnore.endsWith(EOL) || gitIgnore.length === 0 ? '' : EOL
}${VERCEL_OUTPUT_DIR}${EOL}`;
contentModified = true;
}
if (contentModified) {
await writeFile(gitIgnorePath, gitIgnore);
isGitIgnoreUpdated = true;
}
} catch (error) {

View File

@@ -365,6 +365,10 @@ module.exports = async function prepare(session, binaryPath) {
'project-link-dev': {
'package.json': '{}',
},
'project-link-gitignore': {
'package.json': '{}',
'.gitignore': '.output',
},
'project-link-legacy': {
'index.html': 'Hello',
'vercel.json': '{"builds":[{"src":"*.html","use":"@vercel/static"}]}',

View File

@@ -3453,6 +3453,29 @@ test('[vc link --confirm] should not show prompts and autolink', async t => {
);
});
test('[vc link] should not duplicate paths in .gitignore', async t => {
const dir = fixture('project-link-gitignore');
// remove previously linked project if it exists
await remove(path.join(dir, '.vercel'));
const { exitCode, stderr, stdout } = await execa(
binaryPath,
['link', '--confirm', ...defaultArgs],
{ cwd: dir, reject: false }
);
// Ensure the exit code is right
t.is(exitCode, 0, formatOutput({ stderr, stdout }));
// Ensure the message is correct pattern
t.regex(stderr, /Linked to /m);
// Ensure .gitignore is created
const gitignore = await readFile(path.join(dir, '.gitignore'), 'utf8');
t.is(gitignore, '.output\n.vercel\n');
});
test('[vc dev] should show prompts to set up project', async t => {
const dir = fixture('project-link-dev');
const port = 58352;

View File

@@ -5,7 +5,7 @@ describe('getUpdateCommand', () => {
it('should detect update command', async () => {
const updateCommand = await getUpdateCommand();
expect(updateCommand).toEqual(
`yarn add vercel@${isCanary() ? 'canary' : 'latest'}`
`npm i vercel@${isCanary() ? 'canary' : 'latest'}`
);
});
});

View File

@@ -6,7 +6,8 @@ import { join } from 'path';
import stringArgv from 'string-argv';
import { debug } from '@vercel/build-utils';
const versionMap = new Map([
['1.16', '1.16'],
['1.17', '1.17.3'],
['1.16', '1.16.10'],
['1.15', '1.15.8'],
['1.14', '1.14.15'],
['1.13', '1.13.15'],

View File

@@ -1,6 +1,6 @@
{
"name": "@vercel/go",
"version": "1.2.4-canary.3",
"version": "1.2.4-canary.4",
"license": "MIT",
"main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/go",

View File

@@ -5,10 +5,10 @@
{ "src": "subdirectory/index.go", "use": "@vercel/go" }
],
"probes": [
{ "path": "/", "mustContain": "cow:go1.16:RANDOMNESS_PLACEHOLDER" },
{ "path": "/", "mustContain": "cow:go1.17.3:RANDOMNESS_PLACEHOLDER" },
{
"path": "/subdirectory",
"mustContain": "subcow:go1.16:RANDOMNESS_PLACEHOLDER"
"mustContain": "subcow:go1.17.3:RANDOMNESS_PLACEHOLDER"
}
]
}

View File

@@ -1,3 +1,3 @@
module with-nested
go 1.12
go 1.16

View File

@@ -1,7 +1,7 @@
{
"private": false,
"name": "vercel-plugin-go",
"version": "1.0.0-canary.2",
"version": "1.0.0-canary.3",
"main": "dist/index.js",
"license": "MIT",
"files": [
@@ -18,7 +18,7 @@
},
"dependencies": {
"@vercel/build-utils": "2.12.3-canary.18",
"@vercel/go": "1.2.4-canary.3"
"@vercel/go": "1.2.4-canary.4"
},
"devDependencies": {
"@types/node": "*",

View File

@@ -1,6 +1,6 @@
{
"name": "vercel-plugin-node",
"version": "1.12.2-canary.8",
"version": "1.12.2-canary.9",
"license": "MIT",
"main": "./dist/index",
"homepage": "https://vercel.com/docs/runtimes#official-runtimes/node-js",
@@ -33,8 +33,9 @@
"@types/jest": "27.0.2",
"@types/node-fetch": "2",
"@types/test-listen": "1.1.0",
"@types/yazl": "2.4.2",
"@vercel/build-utils": "2.12.3-canary.18",
"@vercel/fun": "1.0.1",
"@vercel/fun": "1.0.3",
"@vercel/ncc": "0.24.0",
"@vercel/nft": "0.14.0",
"@vercel/node-bridge": "2.1.1-canary.2",
@@ -47,7 +48,8 @@
"node-fetch": "2",
"source-map-support": "0.5.12",
"test-listen": "1.1.0",
"ts-morph": "12.0.0"
"ts-morph": "12.0.0",
"yazl": "2.5.1"
},
"jest": {
"preset": "ts-jest",

View File

@@ -6,6 +6,7 @@ import {
readlinkSync,
statSync,
promises as fsp,
existsSync,
} from 'fs';
import {
basename,
@@ -44,6 +45,7 @@ import { AbortController } from 'abort-controller';
import { Register, register } from './typescript';
import { pageToRoute } from './router/page-to-route';
import { isDynamicRoute } from './router/is-dynamic';
import crypto from 'crypto';
export { shouldServe };
export {
@@ -118,9 +120,14 @@ async function downloadInstallAndBundle({
const nodeVersion = await getNodeVersion(entrypointFsDirname);
const spawnOpts = getSpawnOptions({}, nodeVersion);
const installTime = Date.now();
await runNpmInstall(entrypointFsDirname, [], spawnOpts, {}, nodeVersion);
debug(`Install complete [${Date.now() - installTime}ms]`);
// Only run when `package.json` exists.
if (existsSync(join(entrypointFsDirname, 'package.json'))) {
const installTime = Date.now();
await runNpmInstall(entrypointFsDirname, [], spawnOpts, {}, nodeVersion);
debug(`Install complete [${Date.now() - installTime}ms]`);
} else {
debug(`Skip install command for \`vercel-plugin-node\`.`);
}
return {
nodeVersion,
@@ -384,20 +391,23 @@ export async function buildEntrypoint({
entrypoint: string;
config: FunctionConfig;
}) {
// Unique hash that will be used as directory name for `.output`.
const entrypointHash = crypto
.createHash('sha256')
.update(entrypoint)
.digest('hex');
const outputDirPath = join(workPath, '.output');
const { dir, name } = parsePath(entrypoint);
const entrypointWithoutExt = join('/', dir, name);
const entrypointWithoutExtIndex = join(
dir,
name,
name === 'index' ? '' : 'index'
);
const outputWorkPath = join(
outputDirPath,
'server/pages',
entrypointWithoutExtIndex
);
const outputWorkPath = join(outputDirPath, 'inputs', entrypointHash);
const pagesDir = join(outputDirPath, 'server', 'pages');
const pageOutput = join(pagesDir, renameTStoJS(entrypoint));
const nftOutput = `${pageOutput}.nft.json`;
await fsp.mkdir(outputWorkPath, { recursive: true });
await fsp.mkdir(parsePath(pageOutput).dir, { recursive: true });
console.log(`Compiling "${entrypoint}" to "${outputWorkPath}"`);
const shouldAddHelpers =
@@ -471,6 +481,8 @@ export async function buildEntrypoint({
...launcherFiles,
};
const nftFiles: { input: string; output: string }[] = [];
for (const filename of Object.keys(files)) {
const outPath = join(outputWorkPath, filename);
const file = files[filename];
@@ -481,10 +493,36 @@ export async function buildEntrypoint({
const finishPromise = once(ws, 'finish');
file.toStream().pipe(ws);
await finishPromise;
// The `handler` will be `.output/server/pages/api/subdirectory/___vc/__launcher.launcher`
// or `.output/server/pages/api/___vc/__launcher.launcher`.
// This means everything has to be mounted to the `dirname` of the entrypoint.
nftFiles.push({
input: relative(dirname(nftOutput), outPath),
output: join('.output', 'server', 'pages', dirname(entrypoint), filename),
});
}
await fsp.writeFile(
nftOutput,
JSON.stringify({
version: 1,
files: nftFiles,
})
);
await fsp.copyFile(
join(outputWorkPath, renameTStoJS(entrypoint)),
pageOutput
);
let pageKey = relative(pagesDir, pageOutput);
if (process.platform === 'win32') {
pageKey = pageKey.replace(/\\/gm, '/');
}
const pages = {
[entrypointWithoutExtIndex]: {
[pageKey]: {
handler: `${getFileName(LAUNCHER_FILENAME).slice(0, -3)}.launcher`,
runtime: nodeVersion.runtime,
},

View File

@@ -1,6 +1,7 @@
import { join } from 'path';
import path from 'path';
import { parse } from 'url';
import { promises as fsp } from 'fs';
import { ZipFile } from 'yazl';
import { createFunction, Lambda } from '@vercel/fun';
import {
Request,
@@ -11,6 +12,7 @@ import {
Headers,
} from 'node-fetch';
import { build } from '../src';
import { runNpmInstall, streamToBuffer } from '@vercel/build-utils';
interface TestParams {
fixture: string;
@@ -50,40 +52,64 @@ function withFixture<T>(
t: (props: TestParams) => Promise<T>
): () => Promise<T> {
return async () => {
const fixture = join(__dirname, 'fixtures', name);
const fixture = path.join(__dirname, 'fixtures', name);
const functions = new Map<string, Lambda>();
async function fetch(r: RequestInfo, init?: RequestInit) {
const req = new Request(r, init);
const url = parse(req.url);
const pathWithIndex = join(
url.pathname!,
url.pathname!.endsWith('/index') ? '' : 'index'
).substring(1);
const functionPath = url.pathname!.substring(1);
let status = 404;
let headers: HeadersInit = {};
let body: string | Buffer = 'Function not found';
let fn = functions.get(pathWithIndex);
let fn = functions.get(functionPath);
if (!fn) {
const manifest = JSON.parse(
await fsp.readFile(
join(fixture, '.output/functions-manifest.json'),
path.join(fixture, '.output/functions-manifest.json'),
'utf8'
)
);
const functionManifest = manifest.pages[pathWithIndex];
const keyFile = `${functionPath}.js`;
const keyIndex = `${functionPath}/index.js`;
const fnKey = keyFile in manifest.pages ? keyFile : keyIndex;
const functionManifest = manifest.pages[fnKey];
if (functionManifest) {
const dir = join(fixture, '.output/server/pages', pathWithIndex);
const entry = path.join(fixture, '.output/server/pages', fnKey);
const nftFile = JSON.parse(
await fsp.readFile(`${entry}.nft.json`, 'utf8')
);
const zip = new ZipFile();
zip.addFile(
path.join(fixture, '.output/server/pages', fnKey),
path.join('.output/server/pages', fnKey)
);
nftFile.files.forEach((f: { input: string; output: string }) => {
const input = path.join(path.dirname(entry), f.input);
zip.addFile(input, f.output);
});
zip.end();
const handler = path.posix.join(
'.output/server/pages',
path.dirname(fnKey),
functionManifest.handler
);
fn = await createFunction({
Code: {
Directory: dir,
ZipFile: await streamToBuffer(zip.outputStream),
},
Handler: functionManifest.handler,
Handler: handler,
Runtime: functionManifest.runtime,
});
functions.set(pathWithIndex, fn);
functions.set(functionPath, fn);
}
}
@@ -109,6 +135,12 @@ function withFixture<T>(
});
}
if (
await fsp.lstat(path.join(fixture, 'package.json')).catch(() => false)
) {
await runNpmInstall(fixture);
}
await build({ workPath: fixture });
try {

View File

@@ -2537,7 +2537,7 @@
dependencies:
"@types/yargs-parser" "*"
"@types/yazl@^2.4.1":
"@types/yazl@2.4.2", "@types/yazl@^2.4.1":
version "2.4.2"
resolved "https://registry.yarnpkg.com/@types/yazl/-/yazl-2.4.2.tgz#d5f8a4752261badbf1a36e8b49e042dc18ec84bc"
integrity sha512-T+9JH8O2guEjXNxqmybzQ92mJUh2oCwDDMSSimZSe1P+pceZiFROZLYmcbqkzV5EUwz6VwcKXCO2S2yUpra6XQ==
@@ -2613,10 +2613,10 @@
"@typescript-eslint/types" "4.28.0"
eslint-visitor-keys "^2.0.0"
"@vercel/fun@1.0.1":
version "1.0.1"
resolved "https://registry.yarnpkg.com/@vercel/fun/-/fun-1.0.1.tgz#4b25f50c27bbbdca5b7e71f25ef5018701467962"
integrity sha512-v++KDTdKIr0357sm0AbyYk5jLmsqfUlOKhTsaN0Z/XHpk2YJHOLlGFTDzZPt+8i+ofdPG8lCfht729DHNQskJg==
"@vercel/fun@1.0.3":
version "1.0.3"
resolved "https://registry.yarnpkg.com/@vercel/fun/-/fun-1.0.3.tgz#5e5c4921a3a3a35ee129ce063e6b3f5c4b1eae48"
integrity sha512-9LKNosC+Sdx7ZNU7dnj7XXasHzgRkuDnz9+N6JzSVvb0v8KOZN0ky4+wn3c1B0/wF3dTn2W5nEzgmnsrVCDtkQ==
dependencies:
"@tootallnate/once" "2.0.0"
async-listen "1.0.0"
@@ -2629,6 +2629,7 @@
node-fetch "2.6.1"
path-match "1.2.4"
promisepipe "3.0.0"
semver "7.3.5"
stat-mode "0.3.0"
stream-to-promise "2.2.0"
tar "4.4.18"
@@ -8992,10 +8993,10 @@ node-fetch-npm@^2.0.2:
json-parse-better-errors "^1.0.0"
safe-buffer "^5.1.1"
node-fetch@2, node-fetch@^2:
version "2.6.5"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.5.tgz#42735537d7f080a7e5f78b6c549b7146be1742fd"
integrity sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==
node-fetch@2:
version "2.6.6"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.6.tgz#1751a7c01834e8e1697758732e9efb6eeadfaf89"
integrity sha512-Z8/6vRlTUChSdIgMa51jxQ4lrw/Jy5SOW10ObaA47/RElsAN2c5Pn8bTgFGWn/ibwzXTE8qwr1Yzx28vsecXEA==
dependencies:
whatwg-url "^5.0.0"
@@ -9009,6 +9010,13 @@ node-fetch@2.6.1, node-fetch@^2.2.1, node-fetch@^2.3.0, node-fetch@^2.5.0, node-
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
node-fetch@^2:
version "2.6.5"
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.5.tgz#42735537d7f080a7e5f78b6c549b7146be1742fd"
integrity sha512-mmlIVHJEu5rnIxgEgez6b9GgWXbkZj5YZ7fx+2r94a2E+Uirsp6HsPTPlomfdHtpt/B0cdKviwkoaM6pyvUOpQ==
dependencies:
whatwg-url "^5.0.0"
node-gyp-build@^4.2.2:
version "4.2.3"
resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.2.3.tgz#ce6277f853835f718829efb47db20f3e4d9c4739"
@@ -10665,7 +10673,7 @@ semver@6.1.1:
resolved "https://registry.yarnpkg.com/semver/-/semver-6.1.1.tgz#53f53da9b30b2103cd4f15eab3a18ecbcb210c9b"
integrity sha512-rWYq2e5iYW+fFe/oPPtYJxYgjBm8sC4rmoGdUOgBB7VnwKt6HrL793l2voH1UlsyYZpJ4g0wfjnTEO1s1NP2eQ==
semver@7.x, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5:
semver@7.3.5, semver@7.x, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5:
version "7.3.5"
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7"
integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==
@@ -12618,6 +12626,13 @@ yazl@2.4.3:
dependencies:
buffer-crc32 "~0.2.3"
yazl@2.5.1:
version "2.5.1"
resolved "https://registry.yarnpkg.com/yazl/-/yazl-2.5.1.tgz#a3d65d3dd659a5b0937850e8609f22fffa2b5c35"
integrity sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==
dependencies:
buffer-crc32 "~0.2.3"
yn@3.1.1, yn@^3.0.0:
version "3.1.1"
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"