From 1749ce5d089c33e5bc4fb3dd2060252928aa8553 Mon Sep 17 00:00:00 2001 From: Matthew Phillips Date: Fri, 19 May 2023 15:07:14 -0400 Subject: [PATCH] Refactor to be more modular --- packages/astro/src/@types/astro.ts | 4 ++++ packages/astro/src/core/build/generate.ts | 15 +++------------ .../astro/src/core/build/plugins/plugin-pages.ts | 3 ++- packages/astro/src/core/errors/errors-data.ts | 2 +- packages/astro/src/core/redirects/helpers.ts | 5 +++++ packages/astro/src/core/redirects/index.ts | 2 ++ packages/astro/src/core/redirects/validate.ts | 13 +++++++++++++ packages/astro/src/core/render/core.ts | 5 +++-- 8 files changed, 33 insertions(+), 16 deletions(-) create mode 100644 packages/astro/src/core/redirects/helpers.ts create mode 100644 packages/astro/src/core/redirects/index.ts create mode 100644 packages/astro/src/core/redirects/validate.ts diff --git a/packages/astro/src/@types/astro.ts b/packages/astro/src/@types/astro.ts index 311157645..ec9822912 100644 --- a/packages/astro/src/@types/astro.ts +++ b/packages/astro/src/@types/astro.ts @@ -1843,6 +1843,10 @@ export interface RouteData { redirect?: string; } +export type RedirectRouteData = RouteData & { + redirect: string; +} + export type SerializedRouteData = Omit & { generate: undefined; pattern: string; diff --git a/packages/astro/src/core/build/generate.ts b/packages/astro/src/core/build/generate.ts index 1673703a0..11613545c 100644 --- a/packages/astro/src/core/build/generate.ts +++ b/packages/astro/src/core/build/generate.ts @@ -30,11 +30,12 @@ import { runHookBuildGenerated } from '../../integrations/index.js'; import { isHybridOutput } from '../../prerender/utils.js'; import { BEFORE_HYDRATION_SCRIPT_ID, PAGE_SCRIPT_ID } from '../../vite-plugin-scripts/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 { callMiddleware } from '../middleware/callMiddleware.js'; import { createEnvironment, createRenderContext, renderPage } from '../render/index.js'; import { callGetStaticPaths } from '../render/route-cache.js'; +import { getRedirectLocationOrThrow } from '../redirects/index.js'; import { createAssetLink, createModuleScriptsSet, @@ -69,12 +70,6 @@ export function rootRelativeFacadeId(facadeId: string, settings: AstroSettings): return facadeId.slice(fileURLToPath(settings.config.root).length); } -function redirectWithNoLocation() { - throw new AstroError({ - ...AstroErrorData.RedirectWithNoLocation - }); -} - // Determines of a Rollup chunk is an entrypoint page. export function chunkIsPage( settings: AstroSettings, @@ -523,12 +518,8 @@ async function generatePath( switch(response.status) { case 301: case 302: { - const location = response.headers.get("location"); - if(!location) { - return void redirectWithNoLocation(); - } body = ``; - pageData.route.redirect = location; + pageData.route.redirect = getRedirectLocationOrThrow(response.headers) break; } default: { diff --git a/packages/astro/src/core/build/plugins/plugin-pages.ts b/packages/astro/src/core/build/plugins/plugin-pages.ts index 47d5dab5b..aab166372 100644 --- a/packages/astro/src/core/build/plugins/plugin-pages.ts +++ b/packages/astro/src/core/build/plugins/plugin-pages.ts @@ -5,6 +5,7 @@ import { eachPageData, type BuildInternals } from '../internal.js'; import type { AstroBuildPlugin } from '../plugin'; import type { StaticBuildOptions } from '../types'; import { MIDDLEWARE_MODULE_ID } from './plugin-middleware.js'; +import { routeIsRedirect } from '../../redirects/index.js'; function vitePluginPages(opts: StaticBuildOptions, internals: BuildInternals): VitePlugin { return { @@ -28,7 +29,7 @@ function vitePluginPages(opts: StaticBuildOptions, internals: BuildInternals): V let imports = []; let i = 0; for (const pageData of eachPageData(internals)) { - if(pageData.route.type === 'redirect') { + if(routeIsRedirect(pageData.route)) { continue; } const variable = `_page${i}`; diff --git a/packages/astro/src/core/errors/errors-data.ts b/packages/astro/src/core/errors/errors-data.ts index 1a8112626..5c7d3a101 100644 --- a/packages/astro/src/core/errors/errors-data.ts +++ b/packages/astro/src/core/errors/errors-data.ts @@ -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. * * 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: { - // TODO remove title: '`Astro.redirect` is not available in static mode.', code: 3001, message: diff --git a/packages/astro/src/core/redirects/helpers.ts b/packages/astro/src/core/redirects/helpers.ts new file mode 100644 index 000000000..05e4e83a0 --- /dev/null +++ b/packages/astro/src/core/redirects/helpers.ts @@ -0,0 +1,5 @@ +import type { RouteData, RedirectRouteData } from '../../@types/astro'; + +export function routeIsRedirect(route: RouteData | undefined): route is RedirectRouteData { + return route?.type === 'redirect'; +} diff --git a/packages/astro/src/core/redirects/index.ts b/packages/astro/src/core/redirects/index.ts new file mode 100644 index 000000000..1f6996048 --- /dev/null +++ b/packages/astro/src/core/redirects/index.ts @@ -0,0 +1,2 @@ +export { getRedirectLocationOrThrow } from './validate.js'; +export { routeIsRedirect } from './helpers.js'; diff --git a/packages/astro/src/core/redirects/validate.ts b/packages/astro/src/core/redirects/validate.ts new file mode 100644 index 000000000..523d9f578 --- /dev/null +++ b/packages/astro/src/core/redirects/validate.ts @@ -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; +} diff --git a/packages/astro/src/core/render/core.ts b/packages/astro/src/core/render/core.ts index c4930ab94..ec25833e5 100644 --- a/packages/astro/src/core/render/core.ts +++ b/packages/astro/src/core/render/core.ts @@ -8,6 +8,7 @@ import type { RenderContext } from './context.js'; import type { Environment } from './environment.js'; import { createResult } from './result.js'; import { callGetStaticPaths, findPathItemByKey, RouteCache } from './route-cache.js'; +import { routeIsRedirect } from '../redirects/index.js'; interface GetParamsAndPropsOptions { mod: ComponentInstance; @@ -111,11 +112,11 @@ export type RenderPage = { }; export async function renderPage({ mod, renderContext, env, apiContext }: RenderPage) { - if(renderContext.route?.type === 'redirect') { + if(routeIsRedirect(renderContext.route)) { return new Response(null, { status: 301, headers: { - 'location': renderContext.route.redirect! + location: renderContext.route!.redirect } }); }