Allow 200 response for endpoints in build (#5258)
This commit is contained in:
parent
2765115457
commit
74759cf787
5 changed files with 41 additions and 23 deletions
5
.changeset/cool-ducks-mix.md
Normal file
5
.changeset/cool-ducks-mix.md
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
'astro': patch
|
||||||
|
---
|
||||||
|
|
||||||
|
Allow 200 response for endpoints in build
|
|
@ -21,7 +21,7 @@ import {
|
||||||
} from '../../core/path.js';
|
} from '../../core/path.js';
|
||||||
import { runHookBuildGenerated } from '../../integrations/index.js';
|
import { runHookBuildGenerated } from '../../integrations/index.js';
|
||||||
import { BEFORE_HYDRATION_SCRIPT_ID, PAGE_SCRIPT_ID } from '../../vite-plugin-scripts/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 { debug, info } from '../logger/core.js';
|
||||||
import { createEnvironment, createRenderContext, renderPage } from '../render/index.js';
|
import { createEnvironment, createRenderContext, renderPage } from '../render/index.js';
|
||||||
import { callGetStaticPaths } from '../render/route-cache.js';
|
import { callGetStaticPaths } from '../render/route-cache.js';
|
||||||
|
@ -374,18 +374,19 @@ async function generatePath(
|
||||||
const result = await callEndpoint(endpointHandler, env, ctx);
|
const result = await callEndpoint(endpointHandler, env, ctx);
|
||||||
|
|
||||||
if (result.type === 'response') {
|
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 {
|
} else {
|
||||||
const response = await renderPage(mod, ctx, env);
|
const response = await renderPage(mod, ctx, env);
|
||||||
|
throwIfRedirectNotAllowed(response, opts.settings.config);
|
||||||
// If there's a redirect or something, just do nothing.
|
// If there's no body, do nothing
|
||||||
if (response.status !== 200 || !response.body) {
|
if (!response.body) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
body = await response.text();
|
body = await response.text();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 type { Environment, RenderContext } from '../render/index';
|
||||||
|
|
||||||
import { renderEndpoint } from '../../runtime/server/index.js';
|
import { renderEndpoint } from '../../runtime/server/index.js';
|
||||||
|
@ -113,3 +113,15 @@ export async function call(
|
||||||
cookies: context.cookies,
|
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.`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ import { createRequest } from '../core/request.js';
|
||||||
import { createRouteManifest, matchAllRoutes } from '../core/routing/index.js';
|
import { createRouteManifest, matchAllRoutes } from '../core/routing/index.js';
|
||||||
import { resolvePages } from '../core/util.js';
|
import { resolvePages } from '../core/util.js';
|
||||||
import notFoundTemplate, { subpathNotUsedTemplate } from '../template/4xx.js';
|
import notFoundTemplate, { subpathNotUsedTemplate } from '../template/4xx.js';
|
||||||
|
import { throwIfRedirectNotAllowed } from '../core/endpoint/index.js';
|
||||||
|
|
||||||
interface AstroPluginOptions {
|
interface AstroPluginOptions {
|
||||||
settings: AstroSettings;
|
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(
|
async function handleRoute(
|
||||||
matchedRoute: AsyncReturnType<typeof matchRoute>,
|
matchedRoute: AsyncReturnType<typeof matchRoute>,
|
||||||
url: URL,
|
url: URL,
|
||||||
|
|
11
packages/astro/test/fixtures/with-endpoint-routes/src/pages/invalid-redirect.json.ts
vendored
Normal file
11
packages/astro/test/fixtures/with-endpoint-routes/src/pages/invalid-redirect.json.ts
vendored
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
export const get = () => {
|
||||||
|
return new Response(
|
||||||
|
undefined,
|
||||||
|
{
|
||||||
|
status: 301,
|
||||||
|
headers: {
|
||||||
|
Location: 'https://example.com',
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
Loading…
Reference in a new issue