Allow 200 response for endpoints in build (#5258)

This commit is contained in:
Bjorn Lu 2022-11-01 00:58:54 +08:00 committed by GitHub
parent 2765115457
commit 74759cf787
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 41 additions and 23 deletions

View file

@ -0,0 +1,5 @@
---
'astro': patch
---
Allow 200 response for endpoints in build

View file

@ -21,7 +21,7 @@ import {
} from '../../core/path.js';
import { runHookBuildGenerated } from '../../integrations/index.js';
import { BEFORE_HYDRATION_SCRIPT_ID, PAGE_SCRIPT_ID } from '../../vite-plugin-scripts/index.js';
import { call as callEndpoint } from '../endpoint/index.js';
import { call as callEndpoint, throwIfRedirectNotAllowed } from '../endpoint/index.js';
import { debug, info } from '../logger/core.js';
import { createEnvironment, createRenderContext, renderPage } from '../render/index.js';
import { callGetStaticPaths } from '../render/route-cache.js';
@ -374,18 +374,19 @@ async function generatePath(
const result = await callEndpoint(endpointHandler, env, ctx);
if (result.type === 'response') {
throw new Error(`Returning a Response from an endpoint is not supported in SSG mode.`);
throwIfRedirectNotAllowed(result.response, opts.settings.config);
// If there's no body, do nothing
if (!result.response.body) return;
body = await result.response.text();
} else {
body = result.body;
encoding = result.encoding;
}
body = result.body;
encoding = result.encoding;
} else {
const response = await renderPage(mod, ctx, env);
// If there's a redirect or something, just do nothing.
if (response.status !== 200 || !response.body) {
return;
}
throwIfRedirectNotAllowed(response, opts.settings.config);
// If there's no body, do nothing
if (!response.body) return;
body = await response.text();
}

View file

@ -1,4 +1,4 @@
import type { APIContext, EndpointHandler, Params } from '../../@types/astro';
import type { APIContext, AstroConfig, EndpointHandler, Params } from '../../@types/astro';
import type { Environment, RenderContext } from '../render/index';
import { renderEndpoint } from '../../runtime/server/index.js';
@ -113,3 +113,15 @@ export async function call(
cookies: context.cookies,
};
}
function isRedirect(statusCode: number) {
return statusCode >= 300 && statusCode < 400;
}
export function throwIfRedirectNotAllowed(response: Response, config: AstroConfig) {
if (config.output !== 'server' && isRedirect(response.status)) {
throw new Error(
`Redirects are only available when using output: 'server'. Update your Astro config if you need SSR features.`
);
}
}

View file

@ -19,6 +19,7 @@ import { createRequest } from '../core/request.js';
import { createRouteManifest, matchAllRoutes } from '../core/routing/index.js';
import { resolvePages } from '../core/util.js';
import notFoundTemplate, { subpathNotUsedTemplate } from '../template/4xx.js';
import { throwIfRedirectNotAllowed } from '../core/endpoint/index.js';
interface AstroPluginOptions {
settings: AstroSettings;
@ -293,18 +294,6 @@ async function handleRequest(
}
}
function isRedirect(statusCode: number) {
return statusCode >= 300 && statusCode < 400;
}
function throwIfRedirectNotAllowed(response: Response, config: AstroConfig) {
if (config.output !== 'server' && isRedirect(response.status)) {
throw new Error(
`Redirects are only available when using output: 'server'. Update your Astro config if you need SSR features.`
);
}
}
async function handleRoute(
matchedRoute: AsyncReturnType<typeof matchRoute>,
url: URL,

View file

@ -0,0 +1,11 @@
export const get = () => {
return new Response(
undefined,
{
status: 301,
headers: {
Location: 'https://example.com',
}
}
);
};