[cli][dev] fix: creating "api/some-func.js" after "vc dev" now works (#8041)

If there is no `api` directory, then you run `vc dev`, then you create a new function `api/some-func.js`, then this file would not be served as a new function.

This was being caused by incomplete "new file" handling logic. This PR ensures that the proper detection is done in each new file (`getVercelConfig`) that populates key properties (`apiDir`, `apiExtensions`, and extensionless `files`) for determining when a file is used to serve a request.
This commit is contained in:
Sean Massa
2022-06-29 13:37:48 -05:00
committed by GitHub
parent 9a3739bebd
commit bba7cbd411
3 changed files with 58 additions and 2 deletions

View File

@@ -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) {

View File

@@ -0,0 +1,3 @@
{
"version": 2
}

View File

@@ -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);
}
})
);