Refactor to be more modular

This commit is contained in:
Matthew Phillips 2023-05-19 15:07:14 -04:00
parent eed6a72a2a
commit 1749ce5d08
8 changed files with 33 additions and 16 deletions

View file

@ -1843,6 +1843,10 @@ export interface RouteData {
redirect?: string; redirect?: string;
} }
export type RedirectRouteData = RouteData & {
redirect: string;
}
export type SerializedRouteData = Omit<RouteData, 'generate' | 'pattern'> & { export type SerializedRouteData = Omit<RouteData, 'generate' | 'pattern'> & {
generate: undefined; generate: undefined;
pattern: string; pattern: string;

View file

@ -30,11 +30,12 @@ import { runHookBuildGenerated } from '../../integrations/index.js';
import { isHybridOutput } from '../../prerender/utils.js'; import { isHybridOutput } from '../../prerender/utils.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 { callEndpoint, createAPIContext, throwIfRedirectNotAllowed } from '../endpoint/index.js'; import { callEndpoint, createAPIContext, throwIfRedirectNotAllowed } from '../endpoint/index.js';
import { AstroError, AstroErrorData } from '../errors/index.js'; import { AstroError } from '../errors/index.js';
import { debug, info } from '../logger/core.js'; import { debug, info } from '../logger/core.js';
import { callMiddleware } from '../middleware/callMiddleware.js'; import { callMiddleware } from '../middleware/callMiddleware.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';
import { getRedirectLocationOrThrow } from '../redirects/index.js';
import { import {
createAssetLink, createAssetLink,
createModuleScriptsSet, createModuleScriptsSet,
@ -69,12 +70,6 @@ export function rootRelativeFacadeId(facadeId: string, settings: AstroSettings):
return facadeId.slice(fileURLToPath(settings.config.root).length); return facadeId.slice(fileURLToPath(settings.config.root).length);
} }
function redirectWithNoLocation() {
throw new AstroError({
...AstroErrorData.RedirectWithNoLocation
});
}
// Determines of a Rollup chunk is an entrypoint page. // Determines of a Rollup chunk is an entrypoint page.
export function chunkIsPage( export function chunkIsPage(
settings: AstroSettings, settings: AstroSettings,
@ -523,12 +518,8 @@ async function generatePath(
switch(response.status) { switch(response.status) {
case 301: case 301:
case 302: { case 302: {
const location = response.headers.get("location");
if(!location) {
return void redirectWithNoLocation();
}
body = `<!doctype html><meta http-equiv="refresh" content="0;url=${location}" />`; body = `<!doctype html><meta http-equiv="refresh" content="0;url=${location}" />`;
pageData.route.redirect = location; pageData.route.redirect = getRedirectLocationOrThrow(response.headers)
break; break;
} }
default: { default: {

View file

@ -5,6 +5,7 @@ import { eachPageData, type BuildInternals } from '../internal.js';
import type { AstroBuildPlugin } from '../plugin'; import type { AstroBuildPlugin } from '../plugin';
import type { StaticBuildOptions } from '../types'; import type { StaticBuildOptions } from '../types';
import { MIDDLEWARE_MODULE_ID } from './plugin-middleware.js'; import { MIDDLEWARE_MODULE_ID } from './plugin-middleware.js';
import { routeIsRedirect } from '../../redirects/index.js';
function vitePluginPages(opts: StaticBuildOptions, internals: BuildInternals): VitePlugin { function vitePluginPages(opts: StaticBuildOptions, internals: BuildInternals): VitePlugin {
return { return {
@ -28,7 +29,7 @@ function vitePluginPages(opts: StaticBuildOptions, internals: BuildInternals): V
let imports = []; let imports = [];
let i = 0; let i = 0;
for (const pageData of eachPageData(internals)) { for (const pageData of eachPageData(internals)) {
if(pageData.route.type === 'redirect') { if(routeIsRedirect(pageData.route)) {
continue; continue;
} }
const variable = `_page${i}`; const variable = `_page${i}`;

View file

@ -43,9 +43,9 @@ export const AstroErrorData = {
* The `Astro.redirect` function is only available when [Server-side rendering](/en/guides/server-side-rendering/) is enabled. * The `Astro.redirect` function is only available when [Server-side rendering](/en/guides/server-side-rendering/) is enabled.
* *
* To redirect on a static website, the [meta refresh attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta) can be used. Certain hosts also provide config-based redirects (ex: [Netlify redirects](https://docs.netlify.com/routing/redirects/)). * To redirect on a static website, the [meta refresh attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta) can be used. Certain hosts also provide config-based redirects (ex: [Netlify redirects](https://docs.netlify.com/routing/redirects/)).
* @deprecated since version 2.6
*/ */
StaticRedirectNotAvailable: { StaticRedirectNotAvailable: {
// TODO remove
title: '`Astro.redirect` is not available in static mode.', title: '`Astro.redirect` is not available in static mode.',
code: 3001, code: 3001,
message: message:

View file

@ -0,0 +1,5 @@
import type { RouteData, RedirectRouteData } from '../../@types/astro';
export function routeIsRedirect(route: RouteData | undefined): route is RedirectRouteData {
return route?.type === 'redirect';
}

View file

@ -0,0 +1,2 @@
export { getRedirectLocationOrThrow } from './validate.js';
export { routeIsRedirect } from './helpers.js';

View file

@ -0,0 +1,13 @@
import { AstroError, AstroErrorData } from '../errors/index.js';
export function getRedirectLocationOrThrow(headers: Headers): string {
let location = headers.get('location');
if(!location) {
throw new AstroError({
...AstroErrorData.RedirectWithNoLocation
});
}
return location;
}

View file

@ -8,6 +8,7 @@ import type { RenderContext } from './context.js';
import type { Environment } from './environment.js'; import type { Environment } from './environment.js';
import { createResult } from './result.js'; import { createResult } from './result.js';
import { callGetStaticPaths, findPathItemByKey, RouteCache } from './route-cache.js'; import { callGetStaticPaths, findPathItemByKey, RouteCache } from './route-cache.js';
import { routeIsRedirect } from '../redirects/index.js';
interface GetParamsAndPropsOptions { interface GetParamsAndPropsOptions {
mod: ComponentInstance; mod: ComponentInstance;
@ -111,11 +112,11 @@ export type RenderPage = {
}; };
export async function renderPage({ mod, renderContext, env, apiContext }: RenderPage) { export async function renderPage({ mod, renderContext, env, apiContext }: RenderPage) {
if(renderContext.route?.type === 'redirect') { if(routeIsRedirect(renderContext.route)) {
return new Response(null, { return new Response(null, {
status: 301, status: 301,
headers: { headers: {
'location': renderContext.route.redirect! location: renderContext.route!.redirect
} }
}); });
} }