[cli] Remove "now" from variable names in vc dev (#6483)

This commit is contained in:
Nathan Rajlich
2021-07-19 10:32:21 -07:00
committed by GitHub
parent e37e558674
commit 8cc72a6872
9 changed files with 160 additions and 154 deletions

View File

@@ -96,7 +96,7 @@ async function createBuildProcess(
} }
export async function executeBuild( export async function executeBuild(
nowConfig: VercelConfig, vercelConfig: VercelConfig,
devServer: DevServer, devServer: DevServer,
files: BuilderInputs, files: BuilderInputs,
match: BuildMatch, match: BuildMatch,
@@ -263,7 +263,7 @@ export async function executeBuild(
} }
const { output } = result; const { output } = result;
const { cleanUrls } = nowConfig; const { cleanUrls } = vercelConfig;
// Mimic fmeta-util and perform file renaming // Mimic fmeta-util and perform file renaming
Object.entries(output).forEach(([path, value]) => { Object.entries(output).forEach(([path, value]) => {
@@ -359,7 +359,7 @@ export async function executeBuild(
MemorySize: asset.memory || 3008, MemorySize: asset.memory || 3008,
Environment: { Environment: {
Variables: { Variables: {
...nowConfig.env, ...vercelConfig.env,
...asset.environment, ...asset.environment,
...envConfigs.runEnv, ...envConfigs.runEnv,
}, },
@@ -383,7 +383,7 @@ export async function executeBuild(
} }
export async function getBuildMatches( export async function getBuildMatches(
nowConfig: VercelConfig, vercelConfig: VercelConfig,
cwd: string, cwd: string,
output: Output, output: Output,
devServer: DevServer, devServer: DevServer,
@@ -398,7 +398,7 @@ export async function getBuildMatches(
} }
const noMatches: Builder[] = []; const noMatches: Builder[] = [];
const builds = nowConfig.builds || [{ src: '**', use: '@vercel/static' }]; const builds = vercelConfig.builds || [{ src: '**', use: '@vercel/static' }];
for (const buildConfig of builds) { for (const buildConfig of builds) {
let { src = '**', use, config = {} } = buildConfig; let { src = '**', use, config = {} } = buildConfig;

View File

@@ -50,7 +50,7 @@ export async function devRouter(
reqMethod?: string, reqMethod?: string,
routes?: Route[], routes?: Route[],
devServer?: DevServer, devServer?: DevServer,
nowConfig?: VercelConfig, vercelConfig?: VercelConfig,
previousHeaders?: HttpHeadersConfig, previousHeaders?: HttpHeadersConfig,
missRoutes?: Route[], missRoutes?: Route[],
phase?: HandleValue | null phase?: HandleValue | null
@@ -124,14 +124,14 @@ export async function devRouter(
if ( if (
routeConfig.check && routeConfig.check &&
devServer && devServer &&
nowConfig && vercelConfig &&
phase !== 'hit' && phase !== 'hit' &&
!isDestUrl !isDestUrl
) { ) {
const { pathname = '/' } = url.parse(destPath); const { pathname = '/' } = url.parse(destPath);
const hasDestFile = await devServer.hasFilesystem( const hasDestFile = await devServer.hasFilesystem(
pathname, pathname,
nowConfig vercelConfig
); );
if (!hasDestFile) { if (!hasDestFile) {
@@ -144,7 +144,7 @@ export async function devRouter(
reqMethod, reqMethod,
missRoutes, missRoutes,
devServer, devServer,
nowConfig, vercelConfig,
combinedHeaders, combinedHeaders,
[], [],
'miss' 'miss'

View File

@@ -246,20 +246,18 @@ export default class DevServer {
} }
} }
const nowConfig = await this.getVercelConfig(); const vercelConfig = await this.getVercelConfig();
// Update the build matches in case an entrypoint was created or deleted // Update the build matches in case an entrypoint was created or deleted
await this.updateBuildMatches(nowConfig); await this.updateBuildMatches(vercelConfig);
const filesChangedArray = [...filesChanged]; const filesChangedArray = [...filesChanged];
const filesRemovedArray = [...filesRemoved]; const filesRemovedArray = [...filesRemoved];
// Trigger rebuilds of any existing builds that are dependent // Trigger rebuilds of any existing builds that are dependent
// on one of the files that has changed // on one of the files that has changed
const needsRebuild: Map< const needsRebuild: Map<BuildResult, [string | null, BuildMatch]> =
BuildResult, new Map();
[string | null, BuildMatch]
> = new Map();
for (const match of this.buildMatches.values()) { for (const match of this.buildMatches.values()) {
for (const [requestPath, result] of match.buildResults) { for (const [requestPath, result] of match.buildResults) {
@@ -292,13 +290,19 @@ export default class DevServer {
for (const [result, [requestPath, match]] of needsRebuild) { for (const [result, [requestPath, match]] of needsRebuild) {
if ( if (
requestPath === null || requestPath === null ||
(await shouldServe(match, this.files, requestPath, this, nowConfig)) (await shouldServe(
match,
this.files,
requestPath,
this,
vercelConfig
))
) { ) {
this.triggerBuild( this.triggerBuild(
match, match,
requestPath, requestPath,
null, null,
nowConfig, vercelConfig,
result, result,
filesChangedArray, filesChangedArray,
filesRemovedArray filesRemovedArray
@@ -377,12 +381,12 @@ export default class DevServer {
} }
async updateBuildMatches( async updateBuildMatches(
nowConfig: VercelConfig, vercelConfig: VercelConfig,
isInitial = false isInitial = false
): Promise<void> { ): Promise<void> {
const fileList = this.resolveBuildFiles(this.files); const fileList = this.resolveBuildFiles(this.files);
const matches = await getBuildMatches( const matches = await getBuildMatches(
nowConfig, vercelConfig,
this.cwd, this.cwd,
this.output, this.output,
this, this,
@@ -419,7 +423,7 @@ export default class DevServer {
this.buildMatches.set(match.src, match); this.buildMatches.set(match.src, match);
if (!isInitial && needsBlockingBuild(match)) { if (!isInitial && needsBlockingBuild(match)) {
const buildPromise = executeBuild( const buildPromise = executeBuild(
nowConfig, vercelConfig,
this, this,
this.files, this.files,
match, match,
@@ -462,7 +466,7 @@ export default class DevServer {
} }
async invalidateBuildMatches( async invalidateBuildMatches(
nowConfig: VercelConfig, vercelConfig: VercelConfig,
updatedBuilders: string[] updatedBuilders: string[]
): Promise<void> { ): Promise<void> {
if (updatedBuilders.length === 0) { if (updatedBuilders.length === 0) {
@@ -485,7 +489,7 @@ export default class DevServer {
} }
// Re-add the build matches that were just removed, but with the new builder // Re-add the build matches that were just removed, but with the new builder
await this.updateBuildMatches(nowConfig); await this.updateBuildMatches(vercelConfig);
} }
async getLocalEnv(fileName: string, base?: Env): Promise<Env> { async getLocalEnv(fileName: string, base?: Env): Promise<Env> {
@@ -542,26 +546,26 @@ export default class DevServer {
pkg = null, pkg = null,
// The default empty `vercel.json` is used to serve all // The default empty `vercel.json` is used to serve all
// files as static when no `vercel.json` is present // files as static when no `vercel.json` is present
config = { version: 2, [fileNameSymbol]: 'vercel.json' }, vercelConfig = { version: 2, [fileNameSymbol]: 'vercel.json' },
] = await Promise.all([ ] = await Promise.all([
this.readJsonFile<PackageJson>('package.json'), this.readJsonFile<PackageJson>('package.json'),
this.readJsonFile<VercelConfig>(configPath), this.readJsonFile<VercelConfig>(configPath),
]); ]);
await this.validateVercelConfig(config); await this.validateVercelConfig(vercelConfig);
const { error: routeError, routes: maybeRoutes } = getTransformedRoutes({ const { error: routeError, routes: maybeRoutes } = getTransformedRoutes({
nowConfig: config, nowConfig: vercelConfig,
}); });
if (routeError) { if (routeError) {
this.output.prettyError(routeError); this.output.prettyError(routeError);
await this.exit(); await this.exit();
} }
config.routes = maybeRoutes || []; vercelConfig.routes = maybeRoutes || [];
// no builds -> zero config // no builds -> zero config
if (!config.builds || config.builds.length === 0) { if (!vercelConfig.builds || vercelConfig.builds.length === 0) {
const featHandleMiss = true; // enable for zero config const featHandleMiss = true; // enable for zero config
const { projectSettings, cleanUrls, trailingSlash } = config; const { projectSettings, cleanUrls, trailingSlash } = vercelConfig;
const opts = { output: this.output }; const opts = { output: this.output };
const files = (await getFiles(this.cwd, opts)).map(f => const files = (await getFiles(this.cwd, opts)).map(f =>
@@ -578,7 +582,7 @@ export default class DevServer {
errorRoutes, errorRoutes,
} = await detectBuilders(files, pkg, { } = await detectBuilders(files, pkg, {
tag: getDistTag(cliPkg.version) === 'canary' ? 'canary' : 'latest', tag: getDistTag(cliPkg.version) === 'canary' ? 'canary' : 'latest',
functions: config.functions, functions: vercelConfig.functions,
projectSettings: projectSettings || this.projectSettings, projectSettings: projectSettings || this.projectSettings,
featHandleMiss, featHandleMiss,
cleanUrls, cleanUrls,
@@ -601,18 +605,17 @@ export default class DevServer {
builders = builders.filter(filterFrontendBuilds); builders = builders.filter(filterFrontendBuilds);
} }
config.builds = config.builds || []; vercelConfig.builds = vercelConfig.builds || [];
config.builds.push(...builders); vercelConfig.builds.push(...builders);
delete config.functions; delete vercelConfig.functions;
} }
let routes: Route[] = []; let routes: Route[] = [];
const { routes: nowConfigRoutes } = config;
routes.push(...(redirectRoutes || [])); routes.push(...(redirectRoutes || []));
routes.push( routes.push(
...appendRoutesToPhase({ ...appendRoutesToPhase({
routes: nowConfigRoutes, routes: vercelConfig.routes,
newRoutes: rewriteRoutes, newRoutes: rewriteRoutes,
phase: 'filesystem', phase: 'filesystem',
}) })
@@ -623,28 +626,28 @@ export default class DevServer {
phase: 'error', phase: 'error',
}); });
routes.push(...(defaultRoutes || [])); routes.push(...(defaultRoutes || []));
config.routes = routes; vercelConfig.routes = routes;
} }
if (Array.isArray(config.builds)) { if (Array.isArray(vercelConfig.builds)) {
if (this.devCommand) { if (this.devCommand) {
config.builds = config.builds.filter(filterFrontendBuilds); vercelConfig.builds = vercelConfig.builds.filter(filterFrontendBuilds);
} }
// `@vercel/static-build` needs to be the last builder // `@vercel/static-build` needs to be the last builder
// since it might catch all other requests // since it might catch all other requests
config.builds.sort(sortBuilders); vercelConfig.builds.sort(sortBuilders);
} }
await this.validateVercelConfig(config); await this.validateVercelConfig(vercelConfig);
// TODO: temporarily strip and warn since `has` is not implemented yet // TODO: temporarily strip and warn since `has` is not implemented yet
config.routes = (config.routes || []).filter(route => { vercelConfig.routes = (vercelConfig.routes || []).filter(route => {
if ('has' in route) { if ('has' in route) {
if (!this.vercelConfigWarning) { if (!this.vercelConfigWarning) {
this.vercelConfigWarning = true; this.vercelConfigWarning = true;
this.output.warn( this.output.warn(
`The "has" property in ${config[fileNameSymbol]} will be ignored during development. Deployments will work as expected.` `The "has" property in ${vercelConfig[fileNameSymbol]} will be ignored during development. Deployments will work as expected.`
); );
} }
return false; return false;
@@ -652,14 +655,14 @@ export default class DevServer {
return true; return true;
}); });
this.caseSensitive = hasNewRoutingProperties(config); this.caseSensitive = hasNewRoutingProperties(vercelConfig);
this.apiDir = detectApiDirectory(config.builds || []); this.apiDir = detectApiDirectory(vercelConfig.builds || []);
this.apiExtensions = detectApiExtensions(config.builds || []); this.apiExtensions = detectApiExtensions(vercelConfig.builds || []);
// Update the env vars configuration // Update the env vars configuration
let [runEnv, buildEnv] = await Promise.all([ let [runEnv, buildEnv] = await Promise.all([
this.getLocalEnv('.env', config.env), this.getLocalEnv('.env', vercelConfig.env),
this.getLocalEnv('.env.build', config.build?.env), this.getLocalEnv('.env.build', vercelConfig.build?.env),
]); ]);
let allEnv = { ...buildEnv, ...runEnv }; let allEnv = { ...buildEnv, ...runEnv };
@@ -691,7 +694,7 @@ export default class DevServer {
} }
this.envConfigs = { buildEnv, runEnv, allEnv }; this.envConfigs = { buildEnv, runEnv, allEnv };
return config; return vercelConfig;
} }
async readJsonFile<T>( async readJsonFile<T>(
@@ -871,7 +874,7 @@ export default class DevServer {
.replace('[::]', 'localhost') .replace('[::]', 'localhost')
.replace('127.0.0.1', 'localhost'); .replace('127.0.0.1', 'localhost');
const nowConfig = await this.getVercelConfig(); const vercelConfig = await this.getVercelConfig();
const devCommandPromise = this.runDevCommand(); const devCommandPromise = this.runDevCommand();
const files = await getFiles(this.cwd, { output: this.output }); const files = await getFiles(this.cwd, { output: this.output });
@@ -887,13 +890,13 @@ export default class DevServer {
} }
const builders = new Set<string>( const builders = new Set<string>(
(nowConfig.builds || []) (vercelConfig.builds || [])
.filter((b: Builder) => b.use) .filter((b: Builder) => b.use)
.map((b: Builder) => b.use) .map((b: Builder) => b.use)
); );
await installBuilders(builders, this.output); await installBuilders(builders, this.output);
await this.updateBuildMatches(nowConfig, true); await this.updateBuildMatches(vercelConfig, true);
// Updating builders happens lazily, and any builders that were updated // Updating builders happens lazily, and any builders that were updated
// get their "build matches" invalidated so that the new version is used. // get their "build matches" invalidated so that the new version is used.
@@ -901,7 +904,7 @@ export default class DevServer {
this.updateBuildersPromise = updateBuilders(builders, this.output) this.updateBuildersPromise = updateBuilders(builders, this.output)
.then(updatedBuilders => { .then(updatedBuilders => {
this.updateBuildersPromise = null; this.updateBuildersPromise = null;
this.invalidateBuildMatches(nowConfig, updatedBuilders); this.invalidateBuildMatches(vercelConfig, updatedBuilders);
}) })
.catch(err => { .catch(err => {
this.updateBuildersPromise = null; this.updateBuildersPromise = null;
@@ -922,7 +925,7 @@ export default class DevServer {
); );
for (const match of blockingBuilds) { for (const match of blockingBuilds) {
await executeBuild(nowConfig, this, this.files, match, null, true); await executeBuild(vercelConfig, this, this.files, match, null, true);
} }
this.output.success('Build completed'); this.output.success('Build completed');
@@ -1062,21 +1065,21 @@ export default class DevServer {
async send404( async send404(
req: http.IncomingMessage, req: http.IncomingMessage,
res: http.ServerResponse, res: http.ServerResponse,
nowRequestId: string requestId: string
): Promise<void> { ): Promise<void> {
return this.sendError(req, res, nowRequestId, 'NOT_FOUND', 404); return this.sendError(req, res, requestId, 'NOT_FOUND', 404);
} }
async sendError( async sendError(
req: http.IncomingMessage, req: http.IncomingMessage,
res: http.ServerResponse, res: http.ServerResponse,
nowRequestId: string, requestId: string,
errorCode?: string, errorCode?: string,
statusCode: number = 500, statusCode: number = 500,
headers: HttpHeadersConfig = {} headers: HttpHeadersConfig = {}
): Promise<void> { ): Promise<void> {
res.statusCode = statusCode; res.statusCode = statusCode;
this.setResponseHeaders(res, nowRequestId, headers); this.setResponseHeaders(res, requestId, headers);
const http_status_description = generateHttpStatusDescription(statusCode); const http_status_description = generateHttpStatusDescription(statusCode);
const error_code = errorCode || http_status_description; const error_code = errorCode || http_status_description;
@@ -1103,7 +1106,7 @@ export default class DevServer {
http_status_code: statusCode, http_status_code: statusCode,
http_status_description, http_status_description,
error_code, error_code,
now_id: nowRequestId, request_id: requestId,
}); });
} else if (statusCode === 502) { } else if (statusCode === 502) {
view = errorTemplate502({ view = errorTemplate502({
@@ -1111,13 +1114,13 @@ export default class DevServer {
http_status_code: statusCode, http_status_code: statusCode,
http_status_description, http_status_description,
error_code, error_code,
now_id: nowRequestId, request_id: requestId,
}); });
} else { } else {
view = errorTemplate({ view = errorTemplate({
http_status_code: statusCode, http_status_code: statusCode,
http_status_description, http_status_description,
now_id: nowRequestId, request_id: requestId,
}); });
} }
body = errorTemplateBase({ body = errorTemplateBase({
@@ -1135,14 +1138,14 @@ export default class DevServer {
async sendRedirect( async sendRedirect(
req: http.IncomingMessage, req: http.IncomingMessage,
res: http.ServerResponse, res: http.ServerResponse,
nowRequestId: string, requestId: string,
location: string, location: string,
statusCode: number = 302 statusCode: number = 302
): Promise<void> { ): Promise<void> {
this.output.debug(`Redirect ${statusCode}: ${location}`); this.output.debug(`Redirect ${statusCode}: ${location}`);
res.statusCode = statusCode; res.statusCode = statusCode;
this.setResponseHeaders(res, nowRequestId, { location }); this.setResponseHeaders(res, requestId, { location });
let body: string; let body: string;
const { accept = 'text/plain' } = req.headers; const { accept = 'text/plain' } = req.headers;
@@ -1173,14 +1176,14 @@ export default class DevServer {
*/ */
setResponseHeaders( setResponseHeaders(
res: http.ServerResponse, res: http.ServerResponse,
nowRequestId: string, requestId: string,
headers: http.OutgoingHttpHeaders = {} headers: http.OutgoingHttpHeaders = {}
): void { ): void {
const allHeaders = { const allHeaders = {
'cache-control': 'public, max-age=0, must-revalidate', 'cache-control': 'public, max-age=0, must-revalidate',
...headers, ...headers,
server: 'Vercel', server: 'Vercel',
'x-vercel-id': nowRequestId, 'x-vercel-id': requestId,
'x-vercel-cache': 'MISS', 'x-vercel-cache': 'MISS',
}; };
for (const [name, value] of Object.entries(allHeaders)) { for (const [name, value] of Object.entries(allHeaders)) {
@@ -1191,9 +1194,9 @@ export default class DevServer {
/** /**
* Returns the request `headers` that will be sent to the Lambda. * Returns the request `headers` that will be sent to the Lambda.
*/ */
getNowProxyHeaders( getProxyHeaders(
req: http.IncomingMessage, req: http.IncomingMessage,
nowRequestId: string, requestId: string,
xfwd: boolean xfwd: boolean
): http.IncomingHttpHeaders { ): http.IncomingHttpHeaders {
const ip = this.getRequestIp(req); const ip = this.getRequestIp(req);
@@ -1203,7 +1206,7 @@ export default class DevServer {
'x-real-ip': ip, 'x-real-ip': ip,
'x-vercel-deployment-url': host, 'x-vercel-deployment-url': host,
'x-vercel-forwarded-for': ip, 'x-vercel-forwarded-for': ip,
'x-vercel-id': nowRequestId, 'x-vercel-id': requestId,
}; };
if (xfwd) { if (xfwd) {
headers['x-forwarded-host'] = host; headers['x-forwarded-host'] = host;
@@ -1217,7 +1220,7 @@ export default class DevServer {
match: BuildMatch, match: BuildMatch,
requestPath: string | null, requestPath: string | null,
req: http.IncomingMessage | null, req: http.IncomingMessage | null,
nowConfig: VercelConfig, vercelConfig: VercelConfig,
previousBuildResult?: BuildResult, previousBuildResult?: BuildResult,
filesChanged?: string[], filesChanged?: string[],
filesRemoved?: string[] filesRemoved?: string[]
@@ -1253,7 +1256,7 @@ export default class DevServer {
} }
this.output.debug(msg); this.output.debug(msg);
buildPromise = executeBuild( buildPromise = executeBuild(
nowConfig, vercelConfig,
this, this,
this.files, this.files,
match, match,
@@ -1294,11 +1297,11 @@ export default class DevServer {
) => { ) => {
await this.startPromise; await this.startPromise;
let nowRequestId = generateRequestId(this.podId); let requestId = generateRequestId(this.podId);
if (this.stopping) { if (this.stopping) {
res.setHeader('Connection', 'close'); res.setHeader('Connection', 'close');
await this.send404(req, res, nowRequestId); await this.send404(req, res, requestId);
return; return;
} }
@@ -1306,8 +1309,8 @@ export default class DevServer {
this.output.debug(`${chalk.bold(method)} ${req.url}`); this.output.debug(`${chalk.bold(method)} ${req.url}`);
try { try {
const nowConfig = await this.getVercelConfig(); const vercelConfig = await this.getVercelConfig();
await this.serveProjectAsNowV2(req, res, nowRequestId, nowConfig); await this.serveProjectAsNowV2(req, res, requestId, vercelConfig);
} catch (err) { } catch (err) {
console.error(err); console.error(err);
this.output.debug(err.stack); this.output.debug(err.stack);
@@ -1328,20 +1331,20 @@ export default class DevServer {
phase: HandleValue | null, phase: HandleValue | null,
req: http.IncomingMessage, req: http.IncomingMessage,
res: http.ServerResponse, res: http.ServerResponse,
nowRequestId: string requestId: string
): Promise<boolean> => { ): Promise<boolean> => {
const { status, headers, dest } = routeResult; const { status, headers, dest } = routeResult;
const location = headers['location'] || dest; const location = headers['location'] || dest;
if (status && location && 300 <= status && status <= 399) { if (status && location && 300 <= status && status <= 399) {
this.output.debug(`Route found with redirect status code ${status}`); this.output.debug(`Route found with redirect status code ${status}`);
await this.sendRedirect(req, res, nowRequestId, location, status); await this.sendRedirect(req, res, requestId, location, status);
return true; return true;
} }
if (!match && status && phase !== 'miss') { if (!match && status && phase !== 'miss') {
this.output.debug(`Route found with with status code ${status}`); this.output.debug(`Route found with with status code ${status}`);
await this.sendError(req, res, nowRequestId, '', status, headers); await this.sendError(req, res, requestId, '', status, headers);
return true; return true;
} }
@@ -1354,9 +1357,9 @@ export default class DevServer {
serveProjectAsNowV2 = async ( serveProjectAsNowV2 = async (
req: http.IncomingMessage, req: http.IncomingMessage,
res: http.ServerResponse, res: http.ServerResponse,
nowRequestId: string, requestId: string,
nowConfig: VercelConfig, vercelConfig: VercelConfig,
routes: Route[] | undefined = nowConfig.routes, routes: Route[] | undefined = vercelConfig.routes,
callLevel: number = 0 callLevel: number = 0
) => { ) => {
const { debug } = this.output; const { debug } = this.output;
@@ -1373,7 +1376,7 @@ export default class DevServer {
// Only `GET` requests are redirected. // Only `GET` requests are redirected.
// Other methods are normalized without redirecting. // Other methods are normalized without redirecting.
if (req.method === 'GET') { if (req.method === 'GET') {
await this.sendRedirect(req, res, nowRequestId, location, 301); await this.sendRedirect(req, res, requestId, location, 301);
return; return;
} }
@@ -1382,7 +1385,7 @@ export default class DevServer {
} }
if (callLevel === 0) { if (callLevel === 0) {
await this.updateBuildMatches(nowConfig); await this.updateBuildMatches(vercelConfig);
} }
if (this.blockingBuildsPromise) { if (this.blockingBuildsPromise) {
@@ -1424,7 +1427,7 @@ export default class DevServer {
req.method, req.method,
phaseRoutes, phaseRoutes,
this, this,
nowConfig, vercelConfig,
prevHeaders, prevHeaders,
missRoutes, missRoutes,
phase phase
@@ -1444,8 +1447,8 @@ export default class DevServer {
const destUrl = url.format(destParsed); const destUrl = url.format(destParsed);
debug(`ProxyPass: ${destUrl}`); debug(`ProxyPass: ${destUrl}`);
this.setResponseHeaders(res, nowRequestId); this.setResponseHeaders(res, requestId);
return proxyPass(req, res, destUrl, this, nowRequestId); return proxyPass(req, res, destUrl, this, requestId);
} }
match = await findBuildMatch( match = await findBuildMatch(
@@ -1453,7 +1456,7 @@ export default class DevServer {
this.files, this.files,
routeResult.dest, routeResult.dest,
this, this,
nowConfig vercelConfig
); );
if ( if (
@@ -1463,7 +1466,7 @@ export default class DevServer {
phase, phase,
req, req,
res, res,
nowRequestId requestId
) )
) { ) {
return; return;
@@ -1476,7 +1479,7 @@ export default class DevServer {
req.method, req.method,
missRoutes, missRoutes,
this, this,
nowConfig, vercelConfig,
routeResult.headers, routeResult.headers,
[], [],
'miss' 'miss'
@@ -1487,7 +1490,7 @@ export default class DevServer {
this.files, this.files,
routeResult.dest, routeResult.dest,
this, this,
nowConfig vercelConfig
); );
if ( if (
await this.exitWithStatus( await this.exitWithStatus(
@@ -1496,7 +1499,7 @@ export default class DevServer {
phase, phase,
req, req,
res, res,
nowRequestId requestId
) )
) { ) {
return; return;
@@ -1510,7 +1513,7 @@ export default class DevServer {
req.method, req.method,
hitRoutes, hitRoutes,
this, this,
nowConfig, vercelConfig,
routeResult.headers, routeResult.headers,
[], [],
'hit' 'hit'
@@ -1538,7 +1541,7 @@ export default class DevServer {
req.method, req.method,
errorRoutes, errorRoutes,
this, this,
nowConfig, vercelConfig,
routeResult.headers, routeResult.headers,
[], [],
'error' 'error'
@@ -1550,7 +1553,7 @@ export default class DevServer {
this.files, this.files,
routeResultForError.dest, routeResultForError.dest,
this, this,
nowConfig vercelConfig
); );
if (matchForError) { if (matchForError) {
@@ -1569,7 +1572,7 @@ export default class DevServer {
'error', 'error',
req, req,
res, res,
nowRequestId requestId
) )
) { ) {
return; return;
@@ -1611,25 +1614,25 @@ export default class DevServer {
debug(`Proxying to frontend dev server: ${upstream}`); debug(`Proxying to frontend dev server: ${upstream}`);
// Add the Vercel platform proxy request headers // Add the Vercel platform proxy request headers
const headers = this.getNowProxyHeaders(req, nowRequestId, false); const headers = this.getProxyHeaders(req, requestId, false);
for (const [name, value] of Object.entries(headers)) { for (const [name, value] of Object.entries(headers)) {
req.headers[name] = value; req.headers[name] = value;
} }
this.setResponseHeaders(res, nowRequestId); this.setResponseHeaders(res, requestId);
const origUrl = url.parse(req.url || '/', true); const origUrl = url.parse(req.url || '/', true);
delete origUrl.search; delete origUrl.search;
origUrl.pathname = dest; origUrl.pathname = dest;
Object.assign(origUrl.query, uri_args); Object.assign(origUrl.query, uri_args);
req.url = url.format(origUrl); req.url = url.format(origUrl);
return proxyPass(req, res, upstream, this, nowRequestId, false); return proxyPass(req, res, upstream, this, requestId, false);
} }
if ( if (
(statusCode === 404 && routeResult.phase === 'miss') || (statusCode === 404 && routeResult.phase === 'miss') ||
!this.renderDirectoryListing(req, res, requestPath, nowRequestId) !this.renderDirectoryListing(req, res, requestPath, requestId)
) { ) {
await this.send404(req, res, nowRequestId); await this.send404(req, res, requestId);
} }
return; return;
} }
@@ -1655,7 +1658,7 @@ export default class DevServer {
req.method, req.method,
buildResult.routes, buildResult.routes,
this, this,
nowConfig vercelConfig
); );
if (matchedRoute.found && callLevel === 0) { if (matchedRoute.found && callLevel === 0) {
debug(`Found matching route ${matchedRoute.dest} for ${newUrl}`); debug(`Found matching route ${matchedRoute.dest} for ${newUrl}`);
@@ -1663,8 +1666,8 @@ export default class DevServer {
await this.serveProjectAsNowV2( await this.serveProjectAsNowV2(
req, req,
res, res,
nowRequestId, requestId,
nowConfig, vercelConfig,
buildResult.routes, buildResult.routes,
callLevel + 1 callLevel + 1
); );
@@ -1713,7 +1716,7 @@ export default class DevServer {
await this.sendError( await this.sendError(
req, req,
res, res,
nowRequestId, requestId,
'NO_RESPONSE_FROM_FUNCTION', 'NO_RESPONSE_FROM_FUNCTION',
502 502
); );
@@ -1723,7 +1726,7 @@ export default class DevServer {
if (devServerResult) { if (devServerResult) {
// When invoking lambda functions, the region where the lambda was invoked // When invoking lambda functions, the region where the lambda was invoked
// is also included in the request ID. So use the same `dev1` fake region. // is also included in the request ID. So use the same `dev1` fake region.
nowRequestId = generateRequestId(this.podId, true); requestId = generateRequestId(this.podId, true);
const { port, pid } = devServerResult; const { port, pid } = devServerResult;
this.devServerPids.add(pid); this.devServerPids.add(pid);
@@ -1745,31 +1748,31 @@ export default class DevServer {
}); });
// Add the Vercel platform proxy request headers // Add the Vercel platform proxy request headers
const headers = this.getNowProxyHeaders(req, nowRequestId, false); const headers = this.getProxyHeaders(req, requestId, false);
for (const [name, value] of Object.entries(headers)) { for (const [name, value] of Object.entries(headers)) {
req.headers[name] = value; req.headers[name] = value;
} }
this.setResponseHeaders(res, nowRequestId); this.setResponseHeaders(res, requestId);
return proxyPass( return proxyPass(
req, req,
res, res,
`http://localhost:${port}`, `http://localhost:${port}`,
this, this,
nowRequestId, requestId,
false false
); );
} else { } else {
debug(`Skipping \`startDevServer()\` for ${match.entrypoint}`); debug(`Skipping \`startDevServer()\` for ${match.entrypoint}`);
} }
} }
let foundAsset = findAsset(match, requestPath, nowConfig); let foundAsset = findAsset(match, requestPath, vercelConfig);
if (!foundAsset && callLevel === 0) { if (!foundAsset && callLevel === 0) {
await this.triggerBuild(match, buildRequestPath, req, nowConfig); await this.triggerBuild(match, buildRequestPath, req, vercelConfig);
// Since the `asset` was just built, resolve again to get the new asset // Since the `asset` was just built, resolve again to get the new asset
foundAsset = findAsset(match, requestPath, nowConfig); foundAsset = findAsset(match, requestPath, vercelConfig);
} }
// Proxy to the dev server: // Proxy to the dev server:
@@ -1782,24 +1785,24 @@ export default class DevServer {
debug('Proxying to frontend dev server'); debug('Proxying to frontend dev server');
// Add the Vercel platform proxy request headers // Add the Vercel platform proxy request headers
const headers = this.getNowProxyHeaders(req, nowRequestId, false); const headers = this.getProxyHeaders(req, requestId, false);
for (const [name, value] of Object.entries(headers)) { for (const [name, value] of Object.entries(headers)) {
req.headers[name] = value; req.headers[name] = value;
} }
this.setResponseHeaders(res, nowRequestId); this.setResponseHeaders(res, requestId);
return proxyPass( return proxyPass(
req, req,
res, res,
`http://localhost:${this.devProcessPort}`, `http://localhost:${this.devProcessPort}`,
this, this,
nowRequestId, requestId,
false false
); );
} }
if (!foundAsset) { if (!foundAsset) {
await this.send404(req, res, nowRequestId); await this.send404(req, res, requestId);
return; return;
} }
@@ -1813,7 +1816,7 @@ export default class DevServer {
/* eslint-disable no-case-declarations */ /* eslint-disable no-case-declarations */
switch (asset.type) { switch (asset.type) {
case 'FileFsRef': case 'FileFsRef':
this.setResponseHeaders(res, nowRequestId); this.setResponseHeaders(res, requestId);
req.url = `/${basename(asset.fsPath)}`; req.url = `/${basename(asset.fsPath)}`;
return serveStaticFile(req, res, dirname(asset.fsPath), { return serveStaticFile(req, res, dirname(asset.fsPath), {
headers: [ headers: [
@@ -1834,7 +1837,7 @@ export default class DevServer {
'Content-Length': asset.data.length, 'Content-Length': asset.data.length,
'Content-Type': asset.contentType || getMimeType(assetKey), 'Content-Type': asset.contentType || getMimeType(assetKey),
}; };
this.setResponseHeaders(res, nowRequestId, headers); this.setResponseHeaders(res, requestId, headers);
res.end(asset.data); res.end(asset.data);
return; return;
@@ -1846,7 +1849,7 @@ export default class DevServer {
await this.sendError( await this.sendError(
req, req,
res, res,
nowRequestId, requestId,
'INTERNAL_LAMBDA_NOT_FOUND' 'INTERNAL_LAMBDA_NOT_FOUND'
); );
return; return;
@@ -1854,7 +1857,7 @@ export default class DevServer {
// When invoking lambda functions, the region where the lambda was invoked // When invoking lambda functions, the region where the lambda was invoked
// is also included in the request ID. So use the same `dev1` fake region. // is also included in the request ID. So use the same `dev1` fake region.
nowRequestId = generateRequestId(this.podId, true); requestId = generateRequestId(this.podId, true);
// Mix the `routes` result dest query params into the req path // Mix the `routes` result dest query params into the req path
const parsed = url.parse(req.url || '/', true); const parsed = url.parse(req.url || '/', true);
@@ -1871,7 +1874,7 @@ export default class DevServer {
path, path,
headers: { headers: {
...req.headers, ...req.headers,
...this.getNowProxyHeaders(req, nowRequestId, true), ...this.getProxyHeaders(req, requestId, true),
}, },
encoding: 'base64', encoding: 'base64',
body: body.toString('base64'), body: body.toString('base64'),
@@ -1890,7 +1893,7 @@ export default class DevServer {
await this.sendError( await this.sendError(
req, req,
res, res,
nowRequestId, requestId,
'NO_RESPONSE_FROM_FUNCTION', 'NO_RESPONSE_FROM_FUNCTION',
502 502
); );
@@ -1900,7 +1903,7 @@ export default class DevServer {
if (!statusCode) { if (!statusCode) {
res.statusCode = result.statusCode; res.statusCode = result.statusCode;
} }
this.setResponseHeaders(res, nowRequestId, result.headers); this.setResponseHeaders(res, requestId, result.headers);
let resBody: Buffer | string | undefined; let resBody: Buffer | string | undefined;
if (result.encoding === 'base64' && typeof result.body === 'string') { if (result.encoding === 'base64' && typeof result.body === 'string') {
@@ -1912,15 +1915,15 @@ export default class DevServer {
default: default:
// This shouldn't really ever happen... // This shouldn't really ever happen...
await this.sendError(req, res, nowRequestId, 'UNKNOWN_ASSET_TYPE'); await this.sendError(req, res, requestId, 'UNKNOWN_ASSET_TYPE');
} }
}; };
renderDirectoryListing( renderDirectoryListing(
req: http.IncomingMessage, _req: http.IncomingMessage,
res: http.ServerResponse, res: http.ServerResponse,
requestPath: string, requestPath: string,
nowRequestId: string requestId: string
): boolean { ): boolean {
// If the "directory listing" feature is disabled in the // If the "directory listing" feature is disabled in the
// Project's settings, then don't render the directory listing // Project's settings, then don't render the directory listing
@@ -1998,7 +2001,7 @@ export default class DevServer {
paths, paths,
directory, directory,
}); });
this.setResponseHeaders(res, nowRequestId); this.setResponseHeaders(res, requestId);
res.setHeader('Content-Type', 'text/html; charset=utf-8'); res.setHeader('Content-Type', 'text/html; charset=utf-8');
res.setHeader( res.setHeader(
'Content-Length', 'Content-Length',
@@ -2008,14 +2011,17 @@ export default class DevServer {
return true; return true;
} }
async hasFilesystem(dest: string, nowConfig: VercelConfig): Promise<boolean> { async hasFilesystem(
dest: string,
vercelConfig: VercelConfig
): Promise<boolean> {
if ( if (
await findBuildMatch( await findBuildMatch(
this.buildMatches, this.buildMatches,
this.files, this.files,
dest, dest,
this, this,
nowConfig, vercelConfig,
true true
) )
) { ) {
@@ -2121,7 +2127,7 @@ function proxyPass(
res: http.ServerResponse, res: http.ServerResponse,
dest: string, dest: string,
devServer: DevServer, devServer: DevServer,
nowRequestId: string, requestId: string,
ignorePath: boolean = true ignorePath: boolean = true
): void { ): void {
return devServer.proxy.web( return devServer.proxy.web(
@@ -2136,7 +2142,7 @@ function proxyPass(
devServer.sendError( devServer.sendError(
req, req,
res, res,
nowRequestId, requestId,
'NO_RESPONSE_FROM_FUNCTION', 'NO_RESPONSE_FROM_FUNCTION',
502 502
); );
@@ -2197,7 +2203,7 @@ async function findBuildMatch(
files: BuilderInputs, files: BuilderInputs,
requestPath: string, requestPath: string,
devServer: DevServer, devServer: DevServer,
nowConfig: VercelConfig, vercelConfig: VercelConfig,
isFilesystem = false isFilesystem = false
): Promise<BuildMatch | null> { ): Promise<BuildMatch | null> {
requestPath = requestPath.replace(/^\//, ''); requestPath = requestPath.replace(/^\//, '');
@@ -2210,7 +2216,7 @@ async function findBuildMatch(
files, files,
requestPath, requestPath,
devServer, devServer,
nowConfig, vercelConfig,
isFilesystem isFilesystem
) )
) { ) {
@@ -2235,7 +2241,7 @@ async function shouldServe(
files: BuilderInputs, files: BuilderInputs,
requestPath: string, requestPath: string,
devServer: DevServer, devServer: DevServer,
nowConfig: VercelConfig, vercelConfig: VercelConfig,
isFilesystem = false isFilesystem = false
): Promise<boolean> { ): Promise<boolean> {
const { const {
@@ -2249,22 +2255,22 @@ async function shouldServe(
: requestPath; : requestPath;
if ( if (
nowConfig.cleanUrls && vercelConfig.cleanUrls &&
nowConfig.trailingSlash && vercelConfig.trailingSlash &&
cleanSrc === trimmedPath cleanSrc === trimmedPath
) { ) {
// Mimic fmeta-util and convert cleanUrls and trailingSlash // Mimic fmeta-util and convert cleanUrls and trailingSlash
return true; return true;
} else if ( } else if (
nowConfig.cleanUrls && vercelConfig.cleanUrls &&
!nowConfig.trailingSlash && !vercelConfig.trailingSlash &&
cleanSrc === requestPath cleanSrc === requestPath
) { ) {
// Mimic fmeta-util and convert cleanUrls // Mimic fmeta-util and convert cleanUrls
return true; return true;
} else if ( } else if (
!nowConfig.cleanUrls && !vercelConfig.cleanUrls &&
nowConfig.trailingSlash && vercelConfig.trailingSlash &&
src === trimmedPath src === trimmedPath
) { ) {
// Mimic fmeta-util and convert trailingSlash // Mimic fmeta-util and convert trailingSlash
@@ -2280,13 +2286,13 @@ async function shouldServe(
if (shouldServe) { if (shouldServe) {
return true; return true;
} }
} else if (findAsset(match, requestPath, nowConfig)) { } else if (findAsset(match, requestPath, vercelConfig)) {
// If there's no `shouldServe()` function, then look up if there's // If there's no `shouldServe()` function, then look up if there's
// a matching build asset on the `match` that has already been built. // a matching build asset on the `match` that has already been built.
return true; return true;
} else if ( } else if (
!isFilesystem && !isFilesystem &&
(await findMatchingRoute(match, requestPath, devServer, nowConfig)) (await findMatchingRoute(match, requestPath, devServer, vercelConfig))
) { ) {
// If there's no `shouldServe()` function and no matched asset, then look // If there's no `shouldServe()` function and no matched asset, then look
// up if there's a matching build route on the `match` that has already // up if there's a matching build route on the `match` that has already
@@ -2300,7 +2306,7 @@ async function findMatchingRoute(
match: BuildMatch, match: BuildMatch,
requestPath: string, requestPath: string,
devServer: DevServer, devServer: DevServer,
nowConfig: VercelConfig vercelConfig: VercelConfig
): Promise<RouteResult | void> { ): Promise<RouteResult | void> {
const reqUrl = `/${requestPath}`; const reqUrl = `/${requestPath}`;
for (const buildResult of match.buildResults.values()) { for (const buildResult of match.buildResults.values()) {
@@ -2310,7 +2316,7 @@ async function findMatchingRoute(
undefined, undefined,
buildResult.routes, buildResult.routes,
devServer, devServer,
nowConfig vercelConfig
); );
if (route.found) { if (route.found) {
return route; return route;
@@ -2321,7 +2327,7 @@ async function findMatchingRoute(
function findAsset( function findAsset(
match: BuildMatch, match: BuildMatch,
requestPath: string, requestPath: string,
nowConfig: VercelConfig vercelConfig: VercelConfig
): { asset: BuilderOutput; assetKey: string } | void { ): { asset: BuilderOutput; assetKey: string } | void {
if (!match.buildOutput) { if (!match.buildOutput) {
return; return;
@@ -2329,7 +2335,7 @@ function findAsset(
let assetKey: string = requestPath.replace(/\/$/, ''); let assetKey: string = requestPath.replace(/\/$/, '');
let asset = match.buildOutput[requestPath]; let asset = match.buildOutput[requestPath];
if (nowConfig.trailingSlash && requestPath.endsWith('/')) { if (vercelConfig.trailingSlash && requestPath.endsWith('/')) {
asset = match.buildOutput[requestPath.slice(0, -1)]; asset = match.buildOutput[requestPath.slice(0, -1)];
} }
@@ -2413,13 +2419,13 @@ function filterFrontendBuilds(build: Builder) {
return !frontendRuntimeSet.has(name || ''); return !frontendRuntimeSet.has(name || '');
} }
function hasNewRoutingProperties(nowConfig: VercelConfig) { function hasNewRoutingProperties(vercelConfig: VercelConfig) {
return ( return (
typeof nowConfig.cleanUrls !== undefined || typeof vercelConfig.cleanUrls !== undefined ||
typeof nowConfig.headers !== undefined || typeof vercelConfig.headers !== undefined ||
typeof nowConfig.redirects !== undefined || typeof vercelConfig.redirects !== undefined ||
typeof nowConfig.rewrites !== undefined || typeof vercelConfig.rewrites !== undefined ||
typeof nowConfig.trailingSlash !== undefined typeof vercelConfig.trailingSlash !== undefined
); );
} }

View File

@@ -4,6 +4,6 @@
{{? it.error_code }} {{? it.error_code }}
<span class="devinfo-line">Code: <code>{{! it.error_code }}</code></span> <span class="devinfo-line">Code: <code>{{! it.error_code }}</code></span>
{{?}} {{?}}
<span class="devinfo-line">ID: <code>{{! it.now_id }}</code> <span class="devinfo-line">ID: <code>{{! it.request_id }}</code>
</p> </p>
</main> </main>

View File

@@ -2,5 +2,5 @@ interface Inputs {
http_status_code: number; http_status_code: number;
http_status_description: string; http_status_description: string;
error_code?: string; error_code?: string;
now_id: string; request_id: string;
} }

View File

@@ -4,6 +4,6 @@
{{? it.error_code }} {{? it.error_code }}
<span class="devinfo-line">Code: <code>{{! it.error_code }}</code></span> <span class="devinfo-line">Code: <code>{{! it.error_code }}</code></span>
{{?}} {{?}}
<span class="devinfo-line">ID: <code>{{! it.now_id }}</code> <span class="devinfo-line">ID: <code>{{! it.request_id }}</code>
</p> </p>
</main> </main>

View File

@@ -5,5 +5,5 @@ interface Inputs {
http_status_code: number; http_status_code: number;
http_status_description: string; http_status_description: string;
error_code?: string; error_code?: string;
now_id: string; request_id: string;
} }

View File

@@ -38,7 +38,7 @@
{{? it.error_code }} {{? it.error_code }}
<span class="devinfo-line">Code: <code>{{! it.error_code }}</code></span> <span class="devinfo-line">Code: <code>{{! it.error_code }}</code></span>
{{?}} {{?}}
<span class="devinfo-line">ID: <code>{{! it.now_id }}</code> <span class="devinfo-line">ID: <code>{{! it.request_id }}</code>
</p> </p>
{{? it.app_error }} {{? it.app_error }}
<p> <p>

View File

@@ -5,5 +5,5 @@ interface Inputs {
http_status_code: number; http_status_code: number;
http_status_description: string; http_status_description: string;
error_code?: string; error_code?: string;
now_id: string; request_id: string;
} }