Refactor to be more modular
This commit is contained in:
parent
eed6a72a2a
commit
1749ce5d08
8 changed files with 33 additions and 16 deletions
|
@ -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;
|
||||||
|
|
|
@ -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: {
|
||||||
|
|
|
@ -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}`;
|
||||||
|
|
|
@ -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:
|
||||||
|
|
5
packages/astro/src/core/redirects/helpers.ts
Normal file
5
packages/astro/src/core/redirects/helpers.ts
Normal 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';
|
||||||
|
}
|
2
packages/astro/src/core/redirects/index.ts
Normal file
2
packages/astro/src/core/redirects/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export { getRedirectLocationOrThrow } from './validate.js';
|
||||||
|
export { routeIsRedirect } from './helpers.js';
|
13
packages/astro/src/core/redirects/validate.ts
Normal file
13
packages/astro/src/core/redirects/validate.ts
Normal 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;
|
||||||
|
}
|
|
@ -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
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue