mirror of
https://github.com/withastro/astro.git
synced 2025-04-07 23:41:43 -05:00
[ci] format
This commit is contained in:
parent
5acc3135ba
commit
c1671dff22
20 changed files with 429 additions and 206 deletions
|
@ -1,8 +1,4 @@
|
|||
import type {
|
||||
ManifestData,
|
||||
RouteData,
|
||||
SSRManifest,
|
||||
} from '../../@types/astro.js';
|
||||
import type { ManifestData, RouteData, SSRManifest } from '../../@types/astro.js';
|
||||
import type { SinglePageBuiltModule } from '../build/types.js';
|
||||
import { getSetCookiesFromResponse } from '../cookies/index.js';
|
||||
import { consoleLogDestination } from '../logger/console.js';
|
||||
|
@ -20,7 +16,13 @@ import { matchRoute } from '../routing/match.js';
|
|||
import { AppPipeline } from './pipeline.js';
|
||||
import { normalizeTheLocale } from '../../i18n/index.js';
|
||||
import { RenderContext } from '../render-context.js';
|
||||
import { clientAddressSymbol, clientLocalsSymbol, responseSentSymbol, REROUTABLE_STATUS_CODES, REROUTE_DIRECTIVE_HEADER } from '../constants.js';
|
||||
import {
|
||||
clientAddressSymbol,
|
||||
clientLocalsSymbol,
|
||||
responseSentSymbol,
|
||||
REROUTABLE_STATUS_CODES,
|
||||
REROUTE_DIRECTIVE_HEADER,
|
||||
} from '../constants.js';
|
||||
import { AstroError, AstroErrorData } from '../errors/index.js';
|
||||
export { deserializeManifest } from './common.js';
|
||||
|
||||
|
@ -124,7 +126,7 @@ export class App {
|
|||
},
|
||||
serverLike: true,
|
||||
streaming,
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
set setManifestData(newManifestData: ManifestData) {
|
||||
|
@ -294,7 +296,14 @@ export class App {
|
|||
|
||||
let response;
|
||||
try {
|
||||
const renderContext = RenderContext.create({ pipeline: this.#pipeline, locals, pathname, request, routeData, status: defaultStatus })
|
||||
const renderContext = RenderContext.create({
|
||||
pipeline: this.#pipeline,
|
||||
locals,
|
||||
pathname,
|
||||
request,
|
||||
routeData,
|
||||
status: defaultStatus,
|
||||
});
|
||||
response = await renderContext.render(await mod.page());
|
||||
} catch (err: any) {
|
||||
this.#logger.error(null, err.stack || err.message || String(err));
|
||||
|
@ -386,7 +395,7 @@ export class App {
|
|||
request,
|
||||
routeData: errorRouteData,
|
||||
status,
|
||||
})
|
||||
});
|
||||
const response = await renderContext.render(await mod.page());
|
||||
return this.#mergeResponses(response, originalResponse);
|
||||
} catch {
|
||||
|
|
|
@ -1,14 +1,25 @@
|
|||
import type { RouteData, SSRElement, SSRResult } from "../../@types/astro.js";
|
||||
import { Pipeline } from "../base-pipeline.js";
|
||||
import { createModuleScriptElement, createStylesheetElementSet } from "../render/ssr-element.js";
|
||||
import type { RouteData, SSRElement, SSRResult } from '../../@types/astro.js';
|
||||
import { Pipeline } from '../base-pipeline.js';
|
||||
import { createModuleScriptElement, createStylesheetElementSet } from '../render/ssr-element.js';
|
||||
|
||||
export class AppPipeline extends Pipeline {
|
||||
static create({ logger, manifest, mode, renderers, resolve, serverLike, streaming }: Pick<AppPipeline, 'logger' | 'manifest' | 'mode' | 'renderers' | 'resolve' | 'serverLike' | 'streaming'>) {
|
||||
return new AppPipeline(logger, manifest, mode, renderers, resolve, serverLike, streaming);
|
||||
}
|
||||
static create({
|
||||
logger,
|
||||
manifest,
|
||||
mode,
|
||||
renderers,
|
||||
resolve,
|
||||
serverLike,
|
||||
streaming,
|
||||
}: Pick<
|
||||
AppPipeline,
|
||||
'logger' | 'manifest' | 'mode' | 'renderers' | 'resolve' | 'serverLike' | 'streaming'
|
||||
>) {
|
||||
return new AppPipeline(logger, manifest, mode, renderers, resolve, serverLike, streaming);
|
||||
}
|
||||
|
||||
headElements(routeData: RouteData): Pick<SSRResult, 'scripts' | 'styles' | 'links'> {
|
||||
const routeInfo = this.manifest.routes.find(route => route.routeData === routeData);
|
||||
headElements(routeData: RouteData): Pick<SSRResult, 'scripts' | 'styles' | 'links'> {
|
||||
const routeInfo = this.manifest.routes.find((route) => route.routeData === routeData);
|
||||
// may be used in the future for handling rel=modulepreload, rel=icon, rel=manifest etc.
|
||||
const links = new Set<never>();
|
||||
const scripts = new Set<SSRElement>();
|
||||
|
@ -26,7 +37,7 @@ export class AppPipeline extends Pipeline {
|
|||
scripts.add(createModuleScriptElement(script));
|
||||
}
|
||||
}
|
||||
return { links, styles, scripts }
|
||||
return { links, styles, scripts };
|
||||
}
|
||||
|
||||
componentMetadata() {}
|
||||
|
|
|
@ -1,4 +1,11 @@
|
|||
import type { MiddlewareHandler, RouteData, RuntimeMode, SSRLoadedRenderer, SSRManifest, SSRResult } from '../@types/astro.js';
|
||||
import type {
|
||||
MiddlewareHandler,
|
||||
RouteData,
|
||||
RuntimeMode,
|
||||
SSRLoadedRenderer,
|
||||
SSRManifest,
|
||||
SSRResult,
|
||||
} from '../@types/astro.js';
|
||||
import type { Logger } from './logger/core.js';
|
||||
import { RouteCache } from './render/route-cache.js';
|
||||
import { createI18nMiddleware } from '../i18n/middleware.js';
|
||||
|
@ -6,7 +13,7 @@ import { createI18nMiddleware } from '../i18n/middleware.js';
|
|||
/**
|
||||
* The `Pipeline` represents the static parts of rendering that do not change between requests.
|
||||
* These are mostly known when the server first starts up and do not change.
|
||||
*
|
||||
*
|
||||
* Thus, a `Pipeline` is created once at process start and then used by every `RenderContext`.
|
||||
*/
|
||||
export abstract class Pipeline {
|
||||
|
@ -38,13 +45,15 @@ export abstract class Pipeline {
|
|||
/**
|
||||
* Used for `Astro.site`.
|
||||
*/
|
||||
readonly site = manifest.site,
|
||||
readonly site = manifest.site
|
||||
) {
|
||||
this.internalMiddleware = [ createI18nMiddleware(i18n, manifest.base, manifest.trailingSlash, manifest.buildFormat) ];
|
||||
this.internalMiddleware = [
|
||||
createI18nMiddleware(i18n, manifest.base, manifest.trailingSlash, manifest.buildFormat),
|
||||
];
|
||||
}
|
||||
|
||||
abstract headElements(routeData: RouteData): Promise<HeadElements> | HeadElements
|
||||
abstract componentMetadata(routeData: RouteData): Promise<SSRResult['componentMetadata']> | void
|
||||
abstract headElements(routeData: RouteData): Promise<HeadElements> | HeadElements;
|
||||
abstract componentMetadata(routeData: RouteData): Promise<SSRResult['componentMetadata']> | void;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-empty-interface
|
||||
|
|
|
@ -499,7 +499,7 @@ async function generatePath(
|
|||
logger,
|
||||
ssr: serverLike,
|
||||
});
|
||||
const renderContext = RenderContext.create({ pipeline, pathname, request, routeData: route })
|
||||
const renderContext = RenderContext.create({ pipeline, pathname, request, routeData: route });
|
||||
|
||||
let body: string | Uint8Array;
|
||||
let response: Response;
|
||||
|
|
|
@ -4,8 +4,17 @@ import { BEFORE_HYDRATION_SCRIPT_ID, PAGE_SCRIPT_ID } from '../../vite-plugin-sc
|
|||
import type { SSRManifest } from '../app/types.js';
|
||||
import { routeIsFallback, routeIsRedirect } from '../redirects/helpers.js';
|
||||
import { Pipeline } from '../render/index.js';
|
||||
import { createAssetLink, createModuleScriptsSet, createStylesheetElementSet } from '../render/ssr-element.js';
|
||||
import { getPageDataByComponent, type BuildInternals, cssOrder, mergeInlineCss } from './internal.js';
|
||||
import {
|
||||
createAssetLink,
|
||||
createModuleScriptsSet,
|
||||
createStylesheetElementSet,
|
||||
} from '../render/ssr-element.js';
|
||||
import {
|
||||
getPageDataByComponent,
|
||||
type BuildInternals,
|
||||
cssOrder,
|
||||
mergeInlineCss,
|
||||
} from './internal.js';
|
||||
import {
|
||||
ASTRO_PAGE_RESOLVED_MODULE_ID,
|
||||
getVirtualModulePageNameFromPath,
|
||||
|
@ -47,10 +56,22 @@ export class BuildPipeline extends Pipeline {
|
|||
}
|
||||
const serverLike = isServerLikeOutput(config);
|
||||
const streaming = true;
|
||||
super(options.logger, manifest, options.mode, manifest.renderers, resolve, serverLike, streaming)
|
||||
super(
|
||||
options.logger,
|
||||
manifest,
|
||||
options.mode,
|
||||
manifest.renderers,
|
||||
resolve,
|
||||
serverLike,
|
||||
streaming
|
||||
);
|
||||
}
|
||||
|
||||
static create({ internals, manifest, options }: Pick<BuildPipeline, 'internals' | 'manifest' | 'options'>) {
|
||||
static create({
|
||||
internals,
|
||||
manifest,
|
||||
options,
|
||||
}: Pick<BuildPipeline, 'internals' | 'manifest' | 'options'>) {
|
||||
return new BuildPipeline(internals, manifest, options);
|
||||
}
|
||||
|
||||
|
@ -106,17 +127,24 @@ export class BuildPipeline extends Pipeline {
|
|||
}
|
||||
|
||||
headElements(routeData: RouteData): Pick<SSRResult, 'scripts' | 'styles' | 'links'> {
|
||||
const { internals, manifest: { assetsPrefix, base }, settings } = this
|
||||
const {
|
||||
internals,
|
||||
manifest: { assetsPrefix, base },
|
||||
settings,
|
||||
} = this;
|
||||
const links = new Set<never>();
|
||||
const pageBuildData = getPageDataByComponent(internals, routeData.component)
|
||||
const pageBuildData = getPageDataByComponent(internals, routeData.component);
|
||||
const scripts = createModuleScriptsSet(
|
||||
pageBuildData?.hoistedScript ? [pageBuildData.hoistedScript] : [],
|
||||
base,
|
||||
assetsPrefix
|
||||
);
|
||||
const sortedCssAssets = pageBuildData?.styles.sort(cssOrder).map(({ sheet }) => sheet).reduce(mergeInlineCss, []);
|
||||
const sortedCssAssets = pageBuildData?.styles
|
||||
.sort(cssOrder)
|
||||
.map(({ sheet }) => sheet)
|
||||
.reduce(mergeInlineCss, []);
|
||||
const styles = createStylesheetElementSet(sortedCssAssets ?? [], base, assetsPrefix);
|
||||
|
||||
|
||||
if (settings.scripts.some((script) => script.stage === 'page')) {
|
||||
const hashedFilePath = internals.entrySpecifierToBundleMap.get(PAGE_SCRIPT_ID);
|
||||
if (typeof hashedFilePath !== 'string') {
|
||||
|
@ -128,7 +156,7 @@ export class BuildPipeline extends Pipeline {
|
|||
children: '',
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
// Add all injected scripts to the page.
|
||||
for (const script of settings.scripts) {
|
||||
if (script.stage === 'head-inline') {
|
||||
|
@ -138,7 +166,7 @@ export class BuildPipeline extends Pipeline {
|
|||
});
|
||||
}
|
||||
}
|
||||
return { scripts, styles, links }
|
||||
return { scripts, styles, links };
|
||||
}
|
||||
|
||||
componentMetadata() {}
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
import type {
|
||||
APIContext,
|
||||
Locales,
|
||||
Params,
|
||||
} from '../../@types/astro.js';
|
||||
import type { APIContext, Locales, Params } from '../../@types/astro.js';
|
||||
import { ASTRO_VERSION, clientAddressSymbol, clientLocalsSymbol } from '../constants.js';
|
||||
import type { AstroCookies } from '../cookies/index.js';
|
||||
import { AstroError, AstroErrorData } from '../errors/index.js';
|
||||
|
@ -23,7 +19,7 @@ type CreateAPIContext = {
|
|||
routingStrategy: RoutingStrategies | undefined;
|
||||
defaultLocale: string | undefined;
|
||||
route: string;
|
||||
cookies: AstroCookies
|
||||
cookies: AstroCookies;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -41,7 +37,7 @@ export function createAPIContext({
|
|||
routingStrategy,
|
||||
defaultLocale,
|
||||
route,
|
||||
cookies
|
||||
cookies,
|
||||
}: CreateAPIContext): APIContext {
|
||||
let preferredLocale: string | undefined = undefined;
|
||||
let preferredLocaleList: string[] | undefined = undefined;
|
||||
|
|
|
@ -38,12 +38,16 @@ export type CreateContext = {
|
|||
/**
|
||||
* Creates a context to be passed to Astro middleware `onRequest` function.
|
||||
*/
|
||||
function createContext({ request, params = {}, userDefinedLocales = [] }: CreateContext): APIContext {
|
||||
function createContext({
|
||||
request,
|
||||
params = {},
|
||||
userDefinedLocales = [],
|
||||
}: CreateContext): APIContext {
|
||||
let preferredLocale: string | undefined = undefined;
|
||||
let preferredLocaleList: string[] | undefined = undefined;
|
||||
let currentLocale: string | undefined = undefined;
|
||||
const url = new URL(request.url);
|
||||
const route = url.pathname
|
||||
const route = url.pathname;
|
||||
|
||||
return {
|
||||
cookies: new AstroCookies(request),
|
||||
|
@ -61,13 +65,18 @@ function createContext({ request, params = {}, userDefinedLocales = [] }: Create
|
|||
});
|
||||
},
|
||||
get preferredLocale(): string | undefined {
|
||||
return preferredLocale ??= computePreferredLocale(request, userDefinedLocales);
|
||||
return (preferredLocale ??= computePreferredLocale(request, userDefinedLocales));
|
||||
},
|
||||
get preferredLocaleList(): string[] | undefined {
|
||||
return preferredLocaleList ??= computePreferredLocaleList(request, userDefinedLocales);
|
||||
return (preferredLocaleList ??= computePreferredLocaleList(request, userDefinedLocales));
|
||||
},
|
||||
get currentLocale(): string | undefined {
|
||||
return currentLocale ??= computeCurrentLocale(route, userDefinedLocales, undefined, undefined);
|
||||
return (currentLocale ??= computeCurrentLocale(
|
||||
route,
|
||||
userDefinedLocales,
|
||||
undefined,
|
||||
undefined
|
||||
));
|
||||
},
|
||||
url,
|
||||
get clientAddress() {
|
||||
|
|
|
@ -7,4 +7,3 @@ export function routeIsRedirect(route: RouteData | undefined): route is Redirect
|
|||
export function routeIsFallback(route: RouteData | undefined): route is RedirectRouteData {
|
||||
return route?.type === 'fallback';
|
||||
}
|
||||
|
||||
|
|
|
@ -1,18 +1,22 @@
|
|||
import type { RenderContext } from '../render-context.js';
|
||||
|
||||
export async function renderRedirect(renderContext: RenderContext) {
|
||||
const { request: { method }, routeData } = renderContext;
|
||||
const {
|
||||
request: { method },
|
||||
routeData,
|
||||
} = renderContext;
|
||||
const { redirect, redirectRoute } = routeData;
|
||||
const status =
|
||||
redirectRoute && typeof redirect === "object" ? redirect.status
|
||||
: method === "GET" ? 301
|
||||
: 308
|
||||
const headers = { location: redirectRouteGenerate(renderContext) };
|
||||
redirectRoute && typeof redirect === 'object' ? redirect.status : method === 'GET' ? 301 : 308;
|
||||
const headers = { location: redirectRouteGenerate(renderContext) };
|
||||
return new Response(null, { status, headers });
|
||||
}
|
||||
|
||||
function redirectRouteGenerate(renderContext: RenderContext): string {
|
||||
const { params, routeData: { redirect, redirectRoute } } = renderContext;
|
||||
const {
|
||||
params,
|
||||
routeData: { redirect, redirectRoute },
|
||||
} = renderContext;
|
||||
|
||||
if (typeof redirectRoute !== 'undefined') {
|
||||
return redirectRoute?.generate(params) || redirectRoute?.pathname || '/';
|
||||
|
|
|
@ -1,4 +1,9 @@
|
|||
import type { APIContext, ComponentInstance, MiddlewareHandler, RouteData } from '../@types/astro.js';
|
||||
import type {
|
||||
APIContext,
|
||||
ComponentInstance,
|
||||
MiddlewareHandler,
|
||||
RouteData,
|
||||
} from '../@types/astro.js';
|
||||
import { renderEndpoint } from '../runtime/server/endpoint.js';
|
||||
import { attachCookiesToResponse } from './cookies/index.js';
|
||||
import { callMiddleware } from './middleware/callMiddleware.js';
|
||||
|
@ -6,7 +11,12 @@ import { sequence } from './middleware/index.js';
|
|||
import { AstroCookies } from './cookies/index.js';
|
||||
import { createResult } from './render/index.js';
|
||||
import { renderPage } from '../runtime/server/index.js';
|
||||
import { ASTRO_VERSION, ROUTE_TYPE_HEADER, clientAddressSymbol, clientLocalsSymbol } from './constants.js';
|
||||
import {
|
||||
ASTRO_VERSION,
|
||||
ROUTE_TYPE_HEADER,
|
||||
clientAddressSymbol,
|
||||
clientLocalsSymbol,
|
||||
} from './constants.js';
|
||||
import { getParams, getProps, type Pipeline } from './render/index.js';
|
||||
import { AstroError, AstroErrorData } from './errors/index.js';
|
||||
import {
|
||||
|
@ -26,19 +36,36 @@ export class RenderContext {
|
|||
readonly routeData: RouteData,
|
||||
public status: number,
|
||||
readonly cookies = new AstroCookies(request),
|
||||
readonly params = getParams(routeData, pathname),
|
||||
readonly params = getParams(routeData, pathname)
|
||||
) {}
|
||||
|
||||
static create({ locals = {}, middleware, pathname, pipeline, request, routeData, status = 200 }: Pick<RenderContext, 'pathname' |'pipeline' | 'request' | 'routeData'> & Partial<Pick<RenderContext, 'locals' | 'middleware' | 'status'>>) {
|
||||
return new RenderContext(pipeline, locals, sequence(...pipeline.internalMiddleware, middleware ?? pipeline.middleware), pathname, request, routeData, status);
|
||||
static create({
|
||||
locals = {},
|
||||
middleware,
|
||||
pathname,
|
||||
pipeline,
|
||||
request,
|
||||
routeData,
|
||||
status = 200,
|
||||
}: Pick<RenderContext, 'pathname' | 'pipeline' | 'request' | 'routeData'> &
|
||||
Partial<Pick<RenderContext, 'locals' | 'middleware' | 'status'>>) {
|
||||
return new RenderContext(
|
||||
pipeline,
|
||||
locals,
|
||||
sequence(...pipeline.internalMiddleware, middleware ?? pipeline.middleware),
|
||||
pathname,
|
||||
request,
|
||||
routeData,
|
||||
status
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* The main function of the RenderContext.
|
||||
*
|
||||
*
|
||||
* Use this function to render any route known to Astro.
|
||||
* It attempts to render a route. A route can be a:
|
||||
*
|
||||
*
|
||||
* - page
|
||||
* - redirect
|
||||
* - endpoint
|
||||
|
@ -47,25 +74,46 @@ export class RenderContext {
|
|||
async render(componentInstance: ComponentInstance | undefined): Promise<Response> {
|
||||
const { cookies, middleware, pathname, pipeline, routeData } = this;
|
||||
const { logger, routeCache, serverLike, streaming } = pipeline;
|
||||
const props = await getProps({ mod: componentInstance, routeData, routeCache, pathname, logger, serverLike });
|
||||
const props = await getProps({
|
||||
mod: componentInstance,
|
||||
routeData,
|
||||
routeCache,
|
||||
pathname,
|
||||
logger,
|
||||
serverLike,
|
||||
});
|
||||
const apiContext = this.createAPIContext(props);
|
||||
const { type } = routeData;
|
||||
|
||||
|
||||
const lastNext =
|
||||
type === 'endpoint' ? () => renderEndpoint(componentInstance as any, apiContext, serverLike, logger) :
|
||||
type === 'redirect' ? () => renderRedirect(this) :
|
||||
type === 'page' ? async () => {
|
||||
const result = await this.createResult(componentInstance!);
|
||||
const response = await renderPage(result, componentInstance?.default as any, props, {}, streaming, routeData);
|
||||
response.headers.set(ROUTE_TYPE_HEADER, "page");
|
||||
return response;
|
||||
} :
|
||||
type === 'fallback' ? () => new Response(null, { status: 500, headers: { [ROUTE_TYPE_HEADER]: "fallback" } }) :
|
||||
() => { throw new Error("Unknown type of route: " + type) }
|
||||
|
||||
type === 'endpoint'
|
||||
? () => renderEndpoint(componentInstance as any, apiContext, serverLike, logger)
|
||||
: type === 'redirect'
|
||||
? () => renderRedirect(this)
|
||||
: type === 'page'
|
||||
? async () => {
|
||||
const result = await this.createResult(componentInstance!);
|
||||
const response = await renderPage(
|
||||
result,
|
||||
componentInstance?.default as any,
|
||||
props,
|
||||
{},
|
||||
streaming,
|
||||
routeData
|
||||
);
|
||||
response.headers.set(ROUTE_TYPE_HEADER, 'page');
|
||||
return response;
|
||||
}
|
||||
: type === 'fallback'
|
||||
? () =>
|
||||
new Response(null, { status: 500, headers: { [ROUTE_TYPE_HEADER]: 'fallback' } })
|
||||
: () => {
|
||||
throw new Error('Unknown type of route: ' + type);
|
||||
};
|
||||
|
||||
const response = await callMiddleware(middleware, apiContext, lastNext);
|
||||
if (response.headers.get(ROUTE_TYPE_HEADER)) {
|
||||
response.headers.delete(ROUTE_TYPE_HEADER)
|
||||
response.headers.delete(ROUTE_TYPE_HEADER);
|
||||
}
|
||||
// LEGACY: we put cookies on the response object,
|
||||
// where the adapter might be expecting to read it.
|
||||
|
@ -79,11 +127,22 @@ export class RenderContext {
|
|||
const { cookies, i18nData, params, pipeline, request } = this;
|
||||
const { currentLocale, preferredLocale, preferredLocaleList } = i18nData;
|
||||
const generator = `Astro v${ASTRO_VERSION}`;
|
||||
const redirect = (path: string, status = 302) => new Response(null, { status, headers: { Location: path } });
|
||||
const redirect = (path: string, status = 302) =>
|
||||
new Response(null, { status, headers: { Location: path } });
|
||||
const site = pipeline.site ? new URL(pipeline.site) : undefined;
|
||||
const url = new URL(request.url);
|
||||
return {
|
||||
cookies, currentLocale, generator, params, preferredLocale, preferredLocaleList, props, redirect, request, site, url,
|
||||
cookies,
|
||||
currentLocale,
|
||||
generator,
|
||||
params,
|
||||
preferredLocale,
|
||||
preferredLocaleList,
|
||||
props,
|
||||
redirect,
|
||||
request,
|
||||
site,
|
||||
url,
|
||||
get clientAddress() {
|
||||
if (clientAddressSymbol in request) {
|
||||
return Reflect.get(request, clientAddressSymbol) as string;
|
||||
|
@ -110,39 +169,80 @@ export class RenderContext {
|
|||
// where the adapter might be expecting to read it after the response.
|
||||
Reflect.set(request, clientLocalsSymbol, val);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
async createResult(mod: ComponentInstance) {
|
||||
const { cookies, locals, params, pathname, pipeline, request, routeData, status } = this;
|
||||
const { adapterName, clientDirectives, compressHTML, i18n, manifest, logger, renderers, resolve, site, serverLike } = pipeline;
|
||||
const {
|
||||
adapterName,
|
||||
clientDirectives,
|
||||
compressHTML,
|
||||
i18n,
|
||||
manifest,
|
||||
logger,
|
||||
renderers,
|
||||
resolve,
|
||||
site,
|
||||
serverLike,
|
||||
} = pipeline;
|
||||
const { links, scripts, styles } = await pipeline.headElements(routeData);
|
||||
const componentMetadata = await pipeline.componentMetadata(routeData) ?? manifest.componentMetadata;
|
||||
const componentMetadata =
|
||||
(await pipeline.componentMetadata(routeData)) ?? manifest.componentMetadata;
|
||||
const { defaultLocale, locales, routing: routingStrategy } = i18n ?? {};
|
||||
const partial = Boolean(mod.partial);
|
||||
return createResult({ adapterName, clientDirectives, componentMetadata, compressHTML, cookies, defaultLocale, locales, locals, logger, links, params, partial, pathname, renderers, resolve, request, route: routeData.route, routingStrategy, site, scripts, ssr: serverLike, status, styles });
|
||||
return createResult({
|
||||
adapterName,
|
||||
clientDirectives,
|
||||
componentMetadata,
|
||||
compressHTML,
|
||||
cookies,
|
||||
defaultLocale,
|
||||
locales,
|
||||
locals,
|
||||
logger,
|
||||
links,
|
||||
params,
|
||||
partial,
|
||||
pathname,
|
||||
renderers,
|
||||
resolve,
|
||||
request,
|
||||
route: routeData.route,
|
||||
routingStrategy,
|
||||
site,
|
||||
scripts,
|
||||
ssr: serverLike,
|
||||
status,
|
||||
styles,
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* API Context may be created multiple times per request, i18n data needs to be computed only once.
|
||||
* So, it is computed and saved here on creation of the first APIContext and reused for later ones.
|
||||
*/
|
||||
#i18nData?: Pick<APIContext, "currentLocale" | "preferredLocale" | "preferredLocaleList">
|
||||
#i18nData?: Pick<APIContext, 'currentLocale' | 'preferredLocale' | 'preferredLocaleList'>;
|
||||
|
||||
get i18nData() {
|
||||
if (this.#i18nData) return this.#i18nData
|
||||
const { pipeline: { i18n }, request, routeData } = this;
|
||||
if (!i18n) return {
|
||||
currentLocale: undefined,
|
||||
preferredLocale: undefined,
|
||||
preferredLocaleList: undefined
|
||||
}
|
||||
const { defaultLocale, locales, routing } = i18n
|
||||
return this.#i18nData = {
|
||||
if (this.#i18nData) return this.#i18nData;
|
||||
const {
|
||||
pipeline: { i18n },
|
||||
request,
|
||||
routeData,
|
||||
} = this;
|
||||
if (!i18n)
|
||||
return {
|
||||
currentLocale: undefined,
|
||||
preferredLocale: undefined,
|
||||
preferredLocaleList: undefined,
|
||||
};
|
||||
const { defaultLocale, locales, routing } = i18n;
|
||||
return (this.#i18nData = {
|
||||
currentLocale: computeCurrentLocale(routeData.route, locales, routing, defaultLocale),
|
||||
preferredLocale: computePreferredLocale(request, locales),
|
||||
preferredLocaleList: computePreferredLocaleList(request, locales)
|
||||
}
|
||||
preferredLocaleList: computePreferredLocaleList(request, locales),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,11 +24,10 @@ export async function getProps(opts: GetParamsAndPropsOptions): Promise<Props> {
|
|||
return {};
|
||||
}
|
||||
|
||||
|
||||
if (routeIsRedirect(route) || routeIsFallback(route)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
|
||||
// This is a dynamic route, start getting the params
|
||||
const params = getParams(route, pathname);
|
||||
if (mod) {
|
||||
|
|
|
@ -2,7 +2,7 @@ import { appendForwardSlash, joinPaths } from '@astrojs/internal-helpers/path';
|
|||
import type { APIContext, Locales, MiddlewareHandler, SSRManifest } from '../@types/astro.js';
|
||||
import { getPathByLocale, normalizeTheLocale } from './index.js';
|
||||
import { shouldAppendForwardSlash } from '../core/build/util.js';
|
||||
import type { SSRManifestI18n } from '../core/app/types.js'
|
||||
import type { SSRManifestI18n } from '../core/app/types.js';
|
||||
import { ROUTE_TYPE_HEADER } from '../core/constants.js';
|
||||
|
||||
// Checks if the pathname has any locale, exception for the defaultLocale, which is ignored on purpose.
|
||||
|
@ -102,100 +102,100 @@ export function createI18nMiddleware(
|
|||
const type = response.headers.get(ROUTE_TYPE_HEADER);
|
||||
// If the route we're processing is not a page, then we ignore it
|
||||
if (type !== 'page' && type !== 'fallback') {
|
||||
return response
|
||||
return response;
|
||||
}
|
||||
|
||||
const { url, currentLocale } = context;
|
||||
const { locales, defaultLocale, fallback, routing } = i18n;
|
||||
|
||||
switch (i18n.routing) {
|
||||
case 'domains-prefix-other-locales': {
|
||||
if (localeHasntDomain(i18n, currentLocale)) {
|
||||
const result = prefixOtherLocales(url, response);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'pathname-prefix-other-locales': {
|
||||
switch (i18n.routing) {
|
||||
case 'domains-prefix-other-locales': {
|
||||
if (localeHasntDomain(i18n, currentLocale)) {
|
||||
const result = prefixOtherLocales(url, response);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'domains-prefix-always-no-redirect': {
|
||||
if (localeHasntDomain(i18n, currentLocale)) {
|
||||
const result = prefixAlwaysNoRedirect(url, response);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
break;
|
||||
break;
|
||||
}
|
||||
case 'pathname-prefix-other-locales': {
|
||||
const result = prefixOtherLocales(url, response);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'pathname-prefix-always-no-redirect': {
|
||||
case 'domains-prefix-always-no-redirect': {
|
||||
if (localeHasntDomain(i18n, currentLocale)) {
|
||||
const result = prefixAlwaysNoRedirect(url, response);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'pathname-prefix-always': {
|
||||
case 'pathname-prefix-always-no-redirect': {
|
||||
const result = prefixAlwaysNoRedirect(url, response);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case 'pathname-prefix-always': {
|
||||
const result = prefixAlways(url, response, context);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'domains-prefix-always': {
|
||||
if (localeHasntDomain(i18n, currentLocale)) {
|
||||
const result = prefixAlways(url, response, context);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'domains-prefix-always': {
|
||||
if (localeHasntDomain(i18n, currentLocale)) {
|
||||
const result = prefixAlways(url, response, context);
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (response.status >= 300 && fallback) {
|
||||
const fallbackKeys = i18n.fallback ? Object.keys(i18n.fallback) : [];
|
||||
if (response.status >= 300 && fallback) {
|
||||
const fallbackKeys = i18n.fallback ? Object.keys(i18n.fallback) : [];
|
||||
|
||||
// we split the URL using the `/`, and then check in the returned array we have the locale
|
||||
const segments = url.pathname.split('/');
|
||||
const urlLocale = segments.find((segment) => {
|
||||
for (const locale of locales) {
|
||||
if (typeof locale === 'string') {
|
||||
if (locale === segment) {
|
||||
return true;
|
||||
}
|
||||
} else if (locale.path === segment) {
|
||||
// we split the URL using the `/`, and then check in the returned array we have the locale
|
||||
const segments = url.pathname.split('/');
|
||||
const urlLocale = segments.find((segment) => {
|
||||
for (const locale of locales) {
|
||||
if (typeof locale === 'string') {
|
||||
if (locale === segment) {
|
||||
return true;
|
||||
}
|
||||
} else if (locale.path === segment) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
if (urlLocale && fallbackKeys.includes(urlLocale)) {
|
||||
const fallbackLocale = fallback[urlLocale];
|
||||
// the user might have configured the locale using the granular locales, so we want to retrieve its corresponding path instead
|
||||
const pathFallbackLocale = getPathByLocale(fallbackLocale, locales);
|
||||
let newPathname: string;
|
||||
// If a locale falls back to the default locale, we want to **remove** the locale because
|
||||
// the default locale doesn't have a prefix
|
||||
if (pathFallbackLocale === defaultLocale && routing === 'pathname-prefix-other-locales') {
|
||||
newPathname = url.pathname.replace(`/${urlLocale}`, ``);
|
||||
} else {
|
||||
newPathname = url.pathname.replace(`/${urlLocale}`, `/${pathFallbackLocale}`);
|
||||
}
|
||||
|
||||
return context.redirect(newPathname);
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
if (urlLocale && fallbackKeys.includes(urlLocale)) {
|
||||
const fallbackLocale = fallback[urlLocale];
|
||||
// the user might have configured the locale using the granular locales, so we want to retrieve its corresponding path instead
|
||||
const pathFallbackLocale = getPathByLocale(fallbackLocale, locales);
|
||||
let newPathname: string;
|
||||
// If a locale falls back to the default locale, we want to **remove** the locale because
|
||||
// the default locale doesn't have a prefix
|
||||
if (pathFallbackLocale === defaultLocale && routing === 'pathname-prefix-other-locales') {
|
||||
newPathname = url.pathname.replace(`/${urlLocale}`, ``);
|
||||
} else {
|
||||
newPathname = url.pathname.replace(`/${urlLocale}`, `/${pathFallbackLocale}`);
|
||||
}
|
||||
|
||||
return context.redirect(newPathname);
|
||||
}
|
||||
}
|
||||
|
||||
return response;
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
import { bold } from 'kleur/colors';
|
||||
import { REROUTABLE_STATUS_CODES, REROUTE_DIRECTIVE_HEADER } from '../../core/constants.js';;
|
||||
import { REROUTABLE_STATUS_CODES, REROUTE_DIRECTIVE_HEADER } from '../../core/constants.js';
|
||||
import type { APIContext, EndpointHandler } from '../../@types/astro.js';
|
||||
import type { Logger } from '../../core/logger/core.js';
|
||||
|
||||
|
|
|
@ -29,10 +29,7 @@ export function recordServerError(
|
|||
telemetry.record(eventError({ cmd: 'dev', err: errorWithMetadata, isFatal: false }));
|
||||
}
|
||||
|
||||
logger.error(
|
||||
null,
|
||||
formatErrorMessage(errorWithMetadata, logger.level() === 'debug')
|
||||
);
|
||||
logger.error(null, formatErrorMessage(errorWithMetadata, logger.level() === 'debug'));
|
||||
|
||||
return {
|
||||
error: err,
|
||||
|
|
|
@ -1,5 +1,13 @@
|
|||
import url from 'node:url'
|
||||
import type { AstroSettings, ComponentInstance, DevToolbarMetadata, RouteData, SSRElement, SSRLoadedRenderer, SSRManifest } from '../@types/astro.js';
|
||||
import url from 'node:url';
|
||||
import type {
|
||||
AstroSettings,
|
||||
ComponentInstance,
|
||||
DevToolbarMetadata,
|
||||
RouteData,
|
||||
SSRElement,
|
||||
SSRLoadedRenderer,
|
||||
SSRManifest,
|
||||
} from '../@types/astro.js';
|
||||
import type { Logger } from '../core/logger/core.js';
|
||||
import type { ModuleLoader } from '../core/module-loader/index.js';
|
||||
import { Pipeline, loadRenderer } from '../core/render/index.js';
|
||||
|
@ -19,28 +27,38 @@ import { getComponentMetadata } from './metadata.js';
|
|||
export class DevPipeline extends Pipeline {
|
||||
// renderers are loaded on every request,
|
||||
// so it needs to be mutable here unlike in other environments
|
||||
override renderers = new Array<SSRLoadedRenderer>
|
||||
override renderers = new Array<SSRLoadedRenderer>();
|
||||
|
||||
private constructor(
|
||||
readonly loader: ModuleLoader,
|
||||
readonly logger: Logger,
|
||||
readonly manifest: SSRManifest,
|
||||
readonly settings: AstroSettings,
|
||||
readonly config = settings.config,
|
||||
readonly config = settings.config
|
||||
) {
|
||||
const mode = 'development'
|
||||
const mode = 'development';
|
||||
const resolve = createResolve(loader, config.root);
|
||||
const serverLike = isServerLikeOutput(config);
|
||||
const streaming = true;
|
||||
super(logger, manifest, mode, [], resolve, serverLike, streaming);
|
||||
}
|
||||
|
||||
static create({ loader, logger, manifest, settings }: Pick<DevPipeline, 'loader' | 'logger' | 'manifest' | 'settings'>) {
|
||||
return new DevPipeline(loader, logger, manifest, settings)
|
||||
static create({
|
||||
loader,
|
||||
logger,
|
||||
manifest,
|
||||
settings,
|
||||
}: Pick<DevPipeline, 'loader' | 'logger' | 'manifest' | 'settings'>) {
|
||||
return new DevPipeline(loader, logger, manifest, settings);
|
||||
}
|
||||
|
||||
async headElements(routeData: RouteData): Promise<HeadElements> {
|
||||
const { config: { root }, loader, mode, settings } = this;
|
||||
const {
|
||||
config: { root },
|
||||
loader,
|
||||
mode,
|
||||
settings,
|
||||
} = this;
|
||||
const filePath = new URL(`./${routeData.component}`, root);
|
||||
const { scripts } = await getScriptsForURL(filePath, root, loader);
|
||||
|
||||
|
@ -55,9 +73,9 @@ export class DevPipeline extends Pipeline {
|
|||
settings.config.devToolbar.enabled &&
|
||||
(await settings.preferences.get('devToolbar.enabled'))
|
||||
) {
|
||||
const src = await resolveIdToUrl(loader, 'astro/runtime/client/dev-toolbar/entrypoint.js')
|
||||
const src = await resolveIdToUrl(loader, 'astro/runtime/client/dev-toolbar/entrypoint.js');
|
||||
scripts.add({ props: { type: 'module', src }, children: '' });
|
||||
|
||||
|
||||
const additionalMetadata: DevToolbarMetadata['__astro_dev_toolbar__'] = {
|
||||
root: url.fileURLToPath(settings.config.root),
|
||||
version: ASTRO_VERSION,
|
||||
|
@ -69,7 +87,7 @@ export class DevPipeline extends Pipeline {
|
|||
scripts.add({ props: {}, children });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// TODO: We should allow adding generic HTML elements to the head, not just scripts
|
||||
for (const script of settings.scripts) {
|
||||
if (script.stage === 'head-inline') {
|
||||
|
@ -99,15 +117,18 @@ export class DevPipeline extends Pipeline {
|
|||
// But we still want to inject the styles to avoid FOUC. The style tags
|
||||
// should emulate what Vite injects so further HMR works as expected.
|
||||
styles.add({ props: { 'data-vite-dev-id': id }, children: content });
|
||||
};
|
||||
|
||||
return { scripts, styles, links }
|
||||
}
|
||||
|
||||
return { scripts, styles, links };
|
||||
}
|
||||
|
||||
componentMetadata(routeData: RouteData) {
|
||||
const { config: { root }, loader } = this;
|
||||
const {
|
||||
config: { root },
|
||||
loader,
|
||||
} = this;
|
||||
const filePath = new URL(`./${routeData.component}`, root);
|
||||
return getComponentMetadata(filePath, loader)
|
||||
return getComponentMetadata(filePath, loader);
|
||||
}
|
||||
|
||||
async preload(filePath: URL) {
|
||||
|
@ -120,13 +141,13 @@ export class DevPipeline extends Pipeline {
|
|||
|
||||
try {
|
||||
// Load the module from the Vite SSR Runtime.
|
||||
return await loader.import(viteID(filePath)) as ComponentInstance;
|
||||
return (await loader.import(viteID(filePath))) as ComponentInstance;
|
||||
} catch (error) {
|
||||
// If the error came from Markdown or CSS, we already handled it and there's no need to enhance it
|
||||
if (MarkdownError.is(error) || CSSError.is(error) || AggregateError.is(error)) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
|
||||
throw enhanceViteSSRError({ error, filePath, loader });
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,5 @@
|
|||
import type http from 'node:http';
|
||||
import type {
|
||||
ComponentInstance,
|
||||
ManifestData,
|
||||
RouteData,
|
||||
} from '../@types/astro.js';
|
||||
import type { ComponentInstance, ManifestData, RouteData } from '../@types/astro.js';
|
||||
import { AstroErrorData, isAstroError } from '../core/errors/index.js';
|
||||
import { req } from '../core/messages.js';
|
||||
import { loadMiddleware } from '../core/middleware/loadMiddleware.js';
|
||||
|
@ -158,7 +154,7 @@ export async function handleRoute({
|
|||
let options: SSROptions | undefined = undefined;
|
||||
let route: RouteData;
|
||||
const middleware = (await loadMiddleware(loader)).onRequest;
|
||||
|
||||
|
||||
if (!matchedRoute) {
|
||||
if (config.i18n) {
|
||||
const locales = config.i18n.locales;
|
||||
|
@ -208,7 +204,13 @@ export async function handleRoute({
|
|||
fallbackRoutes: [],
|
||||
isIndex: false,
|
||||
};
|
||||
renderContext = RenderContext.create({ pipeline: pipeline, pathname, middleware, request, routeData: route });
|
||||
renderContext = RenderContext.create({
|
||||
pipeline: pipeline,
|
||||
pathname,
|
||||
middleware,
|
||||
request,
|
||||
routeData: route,
|
||||
});
|
||||
} else {
|
||||
return handle404Response(origin, incomingRequest, incomingResponse);
|
||||
}
|
||||
|
@ -217,7 +219,7 @@ export async function handleRoute({
|
|||
const { preloadedComponent } = matchedRoute;
|
||||
route = matchedRoute.route;
|
||||
// Allows adapters to pass in locals in dev mode.
|
||||
const locals = Reflect.get(incomingRequest, clientLocalsSymbol)
|
||||
const locals = Reflect.get(incomingRequest, clientLocalsSymbol);
|
||||
request = createRequest({
|
||||
url,
|
||||
// Headers are only available when using SSR.
|
||||
|
@ -244,7 +246,14 @@ export async function handleRoute({
|
|||
};
|
||||
|
||||
mod = preloadedComponent;
|
||||
renderContext = RenderContext.create({ locals, pipeline, pathname, middleware, request, routeData: route });
|
||||
renderContext = RenderContext.create({
|
||||
locals,
|
||||
pipeline,
|
||||
pathname,
|
||||
middleware,
|
||||
request,
|
||||
routeData: route,
|
||||
});
|
||||
}
|
||||
|
||||
let response = await renderContext.render(mod);
|
||||
|
|
|
@ -21,9 +21,11 @@ describe('core/render', () => {
|
|||
before(async () => {
|
||||
pipeline = createBasicPipeline();
|
||||
pipeline.headElements = () => ({
|
||||
links: new Set([{ name: 'link', props: { rel: 'stylesheet', href: '/main.css' }, children: '' }]),
|
||||
scripts: new Set,
|
||||
styles: new Set
|
||||
links: new Set([
|
||||
{ name: 'link', props: { rel: 'stylesheet', href: '/main.css' }, children: '' },
|
||||
]),
|
||||
scripts: new Set(),
|
||||
styles: new Set(),
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -95,7 +97,12 @@ describe('core/render', () => {
|
|||
|
||||
const PageModule = createAstroModule(Page);
|
||||
const request = new Request('http://example.com/');
|
||||
const routeData = { type: 'page', pathname: '/index', component: 'src/pages/index.astro', params: {} };
|
||||
const routeData = {
|
||||
type: 'page',
|
||||
pathname: '/index',
|
||||
component: 'src/pages/index.astro',
|
||||
params: {},
|
||||
};
|
||||
const renderContext = RenderContext.create({ pipeline, request, routeData });
|
||||
const response = await renderContext.render(PageModule);
|
||||
|
||||
|
@ -171,7 +178,12 @@ describe('core/render', () => {
|
|||
|
||||
const PageModule = createAstroModule(Page);
|
||||
const request = new Request('http://example.com/');
|
||||
const routeData = { type: 'page', pathname: '/index', component: 'src/pages/index.astro', params: {} };
|
||||
const routeData = {
|
||||
type: 'page',
|
||||
pathname: '/index',
|
||||
component: 'src/pages/index.astro',
|
||||
params: {},
|
||||
};
|
||||
const renderContext = RenderContext.create({ pipeline, request, routeData });
|
||||
const response = await renderContext.render(PageModule);
|
||||
|
||||
|
@ -214,7 +226,12 @@ describe('core/render', () => {
|
|||
|
||||
const PageModule = createAstroModule(Page);
|
||||
const request = new Request('http://example.com/');
|
||||
const routeData = { type: 'page', pathname: '/index', component: 'src/pages/index.astro', params: {} };
|
||||
const routeData = {
|
||||
type: 'page',
|
||||
pathname: '/index',
|
||||
component: 'src/pages/index.astro',
|
||||
params: {},
|
||||
};
|
||||
const renderContext = RenderContext.create({ pipeline, request, routeData });
|
||||
const response = await renderContext.render(PageModule);
|
||||
|
||||
|
|
|
@ -43,7 +43,12 @@ describe('core/render', () => {
|
|||
|
||||
const mod = createAstroModule(Page);
|
||||
const request = new Request('http://example.com/');
|
||||
const routeData = { type: 'page', pathname: '/index', component: 'src/pages/index.mdx', params: {} };
|
||||
const routeData = {
|
||||
type: 'page',
|
||||
pathname: '/index',
|
||||
component: 'src/pages/index.mdx',
|
||||
params: {},
|
||||
};
|
||||
const renderContext = RenderContext.create({ pipeline, request, routeData });
|
||||
const response = await renderContext.render(mod);
|
||||
|
||||
|
@ -85,7 +90,12 @@ describe('core/render', () => {
|
|||
|
||||
const mod = createAstroModule(Page);
|
||||
const request = new Request('http://example.com/');
|
||||
const routeData = { type: 'page', pathname: '/index', component: 'src/pages/index.mdx', params: {} };
|
||||
const routeData = {
|
||||
type: 'page',
|
||||
pathname: '/index',
|
||||
component: 'src/pages/index.mdx',
|
||||
params: {},
|
||||
};
|
||||
const renderContext = RenderContext.create({ pipeline, request, routeData });
|
||||
const response = await renderContext.render(mod);
|
||||
|
||||
|
@ -111,7 +121,12 @@ describe('core/render', () => {
|
|||
|
||||
const mod = createAstroModule(Page);
|
||||
const request = new Request('http://example.com/');
|
||||
const routeData = { type: 'page', pathname: '/index', component: 'src/pages/index.mdx', params: {} };
|
||||
const routeData = {
|
||||
type: 'page',
|
||||
pathname: '/index',
|
||||
component: 'src/pages/index.mdx',
|
||||
params: {},
|
||||
};
|
||||
const renderContext = RenderContext.create({ pipeline, request, routeData });
|
||||
const response = await renderContext.render(mod);
|
||||
|
||||
|
|
|
@ -191,7 +191,7 @@ export function createBasicPipeline(options = {}) {
|
|||
options.manifest ?? {},
|
||||
options.mode ?? 'development',
|
||||
options.renderers ?? [],
|
||||
options.resolve ?? (s => Promise.resolve(s)),
|
||||
options.resolve ?? ((s) => Promise.resolve(s)),
|
||||
options.serverLike ?? true,
|
||||
options.streaming ?? true,
|
||||
options.adapterName,
|
||||
|
@ -202,9 +202,9 @@ export function createBasicPipeline(options = {}) {
|
|||
options.routeCache ?? new RouteCache(options.logging, mode),
|
||||
options.site
|
||||
);
|
||||
pipeline.headElements = () => ({ scripts: new Set, styles: new Set, links: new Set });
|
||||
pipeline.headElements = () => ({ scripts: new Set(), styles: new Set(), links: new Set() });
|
||||
pipeline.componentMetadata = () => {};
|
||||
return pipeline
|
||||
return pipeline;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -29,7 +29,7 @@ describe('vite-plugin-astro-server', () => {
|
|||
loader: createLoader({
|
||||
import(id) {
|
||||
if (id === '\0astro-internal:middleware') {
|
||||
return { onRequest: (_, next) => next() }
|
||||
return { onRequest: (_, next) => next() };
|
||||
}
|
||||
const Page = createComponent(() => {
|
||||
return render`<div id="test">testing</div>`;
|
||||
|
@ -62,7 +62,7 @@ describe('vite-plugin-astro-server', () => {
|
|||
controller,
|
||||
incomingRequest: req,
|
||||
incomingResponse: res,
|
||||
manifest: {}
|
||||
manifest: {},
|
||||
});
|
||||
} catch (err) {
|
||||
assert.equal(err.message, undefined);
|
||||
|
|
Loading…
Add table
Reference in a new issue