full site update
This commit is contained in:
348
node_modules/astro/dist/core/render-context.js
generated
vendored
348
node_modules/astro/dist/core/render-context.js
generated
vendored
@@ -1,3 +1,5 @@
|
||||
import { green } from "kleur/colors";
|
||||
import { getActionContext } from "../actions/runtime/virtual/server.js";
|
||||
import { deserializeActionResult } from "../actions/runtime/virtual/shared.js";
|
||||
import { createCallAction, createGetActionResult, hasActionPayload } from "../actions/utils.js";
|
||||
import {
|
||||
@@ -9,38 +11,43 @@ import { renderEndpoint } from "../runtime/server/endpoint.js";
|
||||
import { renderPage } from "../runtime/server/index.js";
|
||||
import {
|
||||
ASTRO_VERSION,
|
||||
clientAddressSymbol,
|
||||
REROUTE_DIRECTIVE_HEADER,
|
||||
REWRITE_DIRECTIVE_HEADER_KEY,
|
||||
REWRITE_DIRECTIVE_HEADER_VALUE,
|
||||
ROUTE_TYPE_HEADER,
|
||||
clientAddressSymbol,
|
||||
clientLocalsSymbol,
|
||||
responseSentSymbol
|
||||
} from "./constants.js";
|
||||
import { AstroCookies, attachCookiesToResponse } from "./cookies/index.js";
|
||||
import { getCookiesFromResponse } from "./cookies/response.js";
|
||||
import { generateCspDigest } from "./encryption.js";
|
||||
import { CspNotEnabled, ForbiddenRewrite } from "./errors/errors-data.js";
|
||||
import { AstroError, AstroErrorData } from "./errors/index.js";
|
||||
import { callMiddleware } from "./middleware/callMiddleware.js";
|
||||
import { sequence } from "./middleware/index.js";
|
||||
import { renderRedirect } from "./redirects/render.js";
|
||||
import { Slots, getParams, getProps } from "./render/index.js";
|
||||
import { isRoute404or500 } from "./routing/match.js";
|
||||
import { copyRequest, setOriginPathname } from "./routing/rewrite.js";
|
||||
import { getParams, getProps, Slots } from "./render/index.js";
|
||||
import { isRoute404or500, isRouteExternalRedirect, isRouteServerIsland } from "./routing/match.js";
|
||||
import { copyRequest, getOriginPathname, setOriginPathname } from "./routing/rewrite.js";
|
||||
import { AstroSession } from "./session.js";
|
||||
const apiContextRoutesSymbol = Symbol.for("context.routes");
|
||||
class RenderContext {
|
||||
constructor(pipeline, locals, middleware, pathname, request, routeData, status, cookies = new AstroCookies(request), params = getParams(routeData, pathname), url = new URL(request.url), props = {}, partial = void 0) {
|
||||
constructor(pipeline, locals, middleware, actions, pathname, request, routeData, status, clientAddress, cookies = new AstroCookies(request), params = getParams(routeData, pathname), url = new URL(request.url), props = {}, partial = void 0, session = pipeline.manifest.sessionConfig ? new AstroSession(cookies, pipeline.manifest.sessionConfig, pipeline.runtimeMode) : void 0) {
|
||||
this.pipeline = pipeline;
|
||||
this.locals = locals;
|
||||
this.middleware = middleware;
|
||||
this.actions = actions;
|
||||
this.pathname = pathname;
|
||||
this.request = request;
|
||||
this.routeData = routeData;
|
||||
this.status = status;
|
||||
this.clientAddress = clientAddress;
|
||||
this.cookies = cookies;
|
||||
this.params = params;
|
||||
this.url = url;
|
||||
this.props = props;
|
||||
this.partial = partial;
|
||||
this.session = session;
|
||||
}
|
||||
/**
|
||||
* A flag that tells the render content if the rewriting was triggered
|
||||
@@ -50,6 +57,7 @@ class RenderContext {
|
||||
* A safety net in case of loops
|
||||
*/
|
||||
counter = 0;
|
||||
result = void 0;
|
||||
static async create({
|
||||
locals = {},
|
||||
middleware,
|
||||
@@ -57,20 +65,30 @@ class RenderContext {
|
||||
pipeline,
|
||||
request,
|
||||
routeData,
|
||||
clientAddress,
|
||||
status = 200,
|
||||
props,
|
||||
partial = void 0
|
||||
partial = void 0,
|
||||
actions
|
||||
}) {
|
||||
const pipelineMiddleware = await pipeline.getMiddleware();
|
||||
setOriginPathname(request, pathname);
|
||||
const pipelineActions = actions ?? await pipeline.getActions();
|
||||
setOriginPathname(
|
||||
request,
|
||||
pathname,
|
||||
pipeline.manifest.trailingSlash,
|
||||
pipeline.manifest.buildFormat
|
||||
);
|
||||
return new RenderContext(
|
||||
pipeline,
|
||||
locals,
|
||||
sequence(...pipeline.internalMiddleware, middleware ?? pipelineMiddleware),
|
||||
pipelineActions,
|
||||
pathname,
|
||||
request,
|
||||
routeData,
|
||||
status,
|
||||
clientAddress,
|
||||
void 0,
|
||||
void 0,
|
||||
void 0,
|
||||
@@ -91,17 +109,18 @@ class RenderContext {
|
||||
*/
|
||||
async render(componentInstance, slots = {}) {
|
||||
const { cookies, middleware, pipeline } = this;
|
||||
const { logger, serverLike, streaming } = pipeline;
|
||||
const isPrerendered = !serverLike || this.routeData.prerender;
|
||||
const { logger, serverLike, streaming, manifest } = pipeline;
|
||||
const props = Object.keys(this.props).length > 0 ? this.props : await getProps({
|
||||
mod: componentInstance,
|
||||
routeData: this.routeData,
|
||||
routeCache: this.pipeline.routeCache,
|
||||
pathname: this.pathname,
|
||||
logger,
|
||||
serverLike
|
||||
serverLike,
|
||||
base: manifest.base
|
||||
});
|
||||
const apiContext = this.createAPIContext(props, isPrerendered);
|
||||
const actionApiContext = this.createActionAPIContext();
|
||||
const apiContext = this.createAPIContext(props, actionApiContext);
|
||||
this.counter++;
|
||||
if (this.counter === 4) {
|
||||
return new Response("Loop Detected", {
|
||||
@@ -112,6 +131,7 @@ class RenderContext {
|
||||
}
|
||||
const lastNext = async (ctx, payload) => {
|
||||
if (payload) {
|
||||
const oldPathname = this.pathname;
|
||||
pipeline.logger.debug("router", "Called rewriting to:", payload);
|
||||
const {
|
||||
routeData,
|
||||
@@ -119,33 +139,64 @@ class RenderContext {
|
||||
pathname,
|
||||
newUrl
|
||||
} = await pipeline.tryRewrite(payload, this.request);
|
||||
if (this.pipeline.serverLike === true && this.routeData.prerender === false && routeData.prerender === true) {
|
||||
throw new AstroError({
|
||||
...ForbiddenRewrite,
|
||||
message: ForbiddenRewrite.message(this.pathname, pathname, routeData.component),
|
||||
hint: ForbiddenRewrite.hint(routeData.component)
|
||||
});
|
||||
}
|
||||
this.routeData = routeData;
|
||||
componentInstance = newComponent;
|
||||
if (payload instanceof Request) {
|
||||
this.request = payload;
|
||||
} else {
|
||||
this.request = copyRequest(newUrl, this.request);
|
||||
this.request = copyRequest(
|
||||
newUrl,
|
||||
this.request,
|
||||
// need to send the flag of the previous routeData
|
||||
routeData.prerender,
|
||||
this.pipeline.logger,
|
||||
this.routeData.route
|
||||
);
|
||||
}
|
||||
this.isRewriting = true;
|
||||
this.url = new URL(this.request.url);
|
||||
this.cookies = new AstroCookies(this.request);
|
||||
this.params = getParams(routeData, pathname);
|
||||
this.pathname = pathname;
|
||||
this.status = 200;
|
||||
setOriginPathname(
|
||||
this.request,
|
||||
oldPathname,
|
||||
this.pipeline.manifest.trailingSlash,
|
||||
this.pipeline.manifest.buildFormat
|
||||
);
|
||||
}
|
||||
let response2;
|
||||
if (!ctx.isPrerendered) {
|
||||
const { action, setActionResult, serializeActionResult } = getActionContext(ctx);
|
||||
if (action?.calledFrom === "form") {
|
||||
const actionResult = await action.handler();
|
||||
setActionResult(action.name, serializeActionResult(actionResult));
|
||||
}
|
||||
}
|
||||
switch (this.routeData.type) {
|
||||
case "endpoint": {
|
||||
response2 = await renderEndpoint(componentInstance, ctx, serverLike, logger);
|
||||
response2 = await renderEndpoint(
|
||||
componentInstance,
|
||||
ctx,
|
||||
this.routeData.prerender,
|
||||
logger
|
||||
);
|
||||
break;
|
||||
}
|
||||
case "redirect":
|
||||
return renderRedirect(this);
|
||||
case "page": {
|
||||
const result = await this.createResult(componentInstance);
|
||||
this.result = await this.createResult(componentInstance, actionApiContext);
|
||||
try {
|
||||
response2 = await renderPage(
|
||||
result,
|
||||
this.result,
|
||||
componentInstance?.default,
|
||||
props,
|
||||
slots,
|
||||
@@ -153,7 +204,7 @@ class RenderContext {
|
||||
this.routeData
|
||||
);
|
||||
} catch (e) {
|
||||
result.cancelled = true;
|
||||
this.result.cancelled = true;
|
||||
throw e;
|
||||
}
|
||||
response2.headers.set(ROUTE_TYPE_HEADER, "page");
|
||||
@@ -175,6 +226,9 @@ class RenderContext {
|
||||
}
|
||||
return response2;
|
||||
};
|
||||
if (isRouteExternalRedirect(this.routeData)) {
|
||||
return renderRedirect(this);
|
||||
}
|
||||
const response = await callMiddleware(middleware, apiContext, lastNext);
|
||||
if (response.headers.get(ROUTE_TYPE_HEADER)) {
|
||||
response.headers.delete(ROUTE_TYPE_HEADER);
|
||||
@@ -182,33 +236,43 @@ class RenderContext {
|
||||
attachCookiesToResponse(response, cookies);
|
||||
return response;
|
||||
}
|
||||
createAPIContext(props, isPrerendered) {
|
||||
const context = this.createActionAPIContext();
|
||||
createAPIContext(props, context) {
|
||||
const redirect = (path, status = 302) => new Response(null, { status, headers: { Location: path } });
|
||||
Reflect.set(context, apiContextRoutesSymbol, this.pipeline);
|
||||
return Object.assign(context, {
|
||||
props,
|
||||
redirect,
|
||||
getActionResult: createGetActionResult(context.locals),
|
||||
callAction: createCallAction(context),
|
||||
// Used internally by Actions middleware.
|
||||
// TODO: discuss exposing this information from APIContext.
|
||||
// middleware runs on prerendered routes in the dev server,
|
||||
// so this is useful information to have.
|
||||
_isPrerendered: isPrerendered
|
||||
callAction: createCallAction(context)
|
||||
});
|
||||
}
|
||||
async #executeRewrite(reroutePayload) {
|
||||
this.pipeline.logger.debug("router", "Calling rewrite: ", reroutePayload);
|
||||
const oldPathname = this.pathname;
|
||||
const { routeData, componentInstance, newUrl, pathname } = await this.pipeline.tryRewrite(
|
||||
reroutePayload,
|
||||
this.request
|
||||
);
|
||||
const isI18nFallback = routeData.fallbackRoutes && routeData.fallbackRoutes.length > 0;
|
||||
if (this.pipeline.serverLike && !this.routeData.prerender && routeData.prerender && !isI18nFallback) {
|
||||
throw new AstroError({
|
||||
...ForbiddenRewrite,
|
||||
message: ForbiddenRewrite.message(this.pathname, pathname, routeData.component),
|
||||
hint: ForbiddenRewrite.hint(routeData.component)
|
||||
});
|
||||
}
|
||||
this.routeData = routeData;
|
||||
if (reroutePayload instanceof Request) {
|
||||
this.request = reroutePayload;
|
||||
} else {
|
||||
this.request = copyRequest(newUrl, this.request);
|
||||
this.request = copyRequest(
|
||||
newUrl,
|
||||
this.request,
|
||||
// need to send the flag of the previous routeData
|
||||
routeData.prerender,
|
||||
this.pipeline.logger,
|
||||
this.routeData.route
|
||||
);
|
||||
}
|
||||
this.url = new URL(this.request.url);
|
||||
this.cookies = new AstroCookies(this.request);
|
||||
@@ -216,6 +280,12 @@ class RenderContext {
|
||||
this.pathname = pathname;
|
||||
this.isRewriting = true;
|
||||
this.status = 200;
|
||||
setOriginPathname(
|
||||
this.request,
|
||||
oldPathname,
|
||||
this.pipeline.manifest.trailingSlash,
|
||||
this.pipeline.manifest.buildFormat
|
||||
);
|
||||
return await this.render(componentInstance);
|
||||
}
|
||||
createActionAPIContext() {
|
||||
@@ -227,8 +297,10 @@ class RenderContext {
|
||||
};
|
||||
return {
|
||||
cookies,
|
||||
routePattern: this.routeData.route,
|
||||
isPrerendered: this.routeData.prerender,
|
||||
get clientAddress() {
|
||||
return renderContext.clientAddress();
|
||||
return renderContext.getClientAddress();
|
||||
},
|
||||
get currentLocale() {
|
||||
return renderContext.computeCurrentLocale();
|
||||
@@ -237,14 +309,8 @@ class RenderContext {
|
||||
get locals() {
|
||||
return renderContext.locals;
|
||||
},
|
||||
// TODO(breaking): disallow replacing the locals object
|
||||
set locals(val) {
|
||||
if (typeof val !== "object") {
|
||||
throw new AstroError(AstroErrorData.LocalsNotAnObject);
|
||||
} else {
|
||||
renderContext.locals = val;
|
||||
Reflect.set(this.request, clientLocalsSymbol, val);
|
||||
}
|
||||
set locals(_) {
|
||||
throw new AstroError(AstroErrorData.LocalsReassigned);
|
||||
},
|
||||
params,
|
||||
get preferredLocale() {
|
||||
@@ -256,19 +322,82 @@ class RenderContext {
|
||||
rewrite,
|
||||
request: this.request,
|
||||
site: pipeline.site,
|
||||
url
|
||||
url,
|
||||
get originPathname() {
|
||||
return getOriginPathname(renderContext.request);
|
||||
},
|
||||
get session() {
|
||||
if (this.isPrerendered) {
|
||||
pipeline.logger.warn(
|
||||
"session",
|
||||
`context.session was used when rendering the route ${green(this.routePattern)}, but it is not available on prerendered routes. If you need access to sessions, make sure that the route is server-rendered using \`export const prerender = false;\` or by setting \`output\` to \`"server"\` in your Astro config to make all your routes server-rendered by default. For more information, see https://docs.astro.build/en/guides/sessions/`
|
||||
);
|
||||
return void 0;
|
||||
}
|
||||
if (!renderContext.session) {
|
||||
pipeline.logger.warn(
|
||||
"session",
|
||||
`context.session was used when rendering the route ${green(this.routePattern)}, but no storage configuration was provided. Either configure the storage manually or use an adapter that provides session storage. For more information, see https://docs.astro.build/en/guides/sessions/`
|
||||
);
|
||||
return void 0;
|
||||
}
|
||||
return renderContext.session;
|
||||
},
|
||||
insertDirective(payload) {
|
||||
if (!pipeline.manifest.csp) {
|
||||
throw new AstroError(CspNotEnabled);
|
||||
}
|
||||
renderContext.result?.directives.push(payload);
|
||||
},
|
||||
insertScriptResource(resource) {
|
||||
if (!pipeline.manifest.csp) {
|
||||
throw new AstroError(CspNotEnabled);
|
||||
}
|
||||
renderContext.result?.scriptResources.push(resource);
|
||||
},
|
||||
insertStyleResource(resource) {
|
||||
if (!pipeline.manifest.csp) {
|
||||
throw new AstroError(CspNotEnabled);
|
||||
}
|
||||
renderContext.result?.styleResources.push(resource);
|
||||
},
|
||||
insertStyleHash(hash) {
|
||||
if (!pipeline.manifest.csp) {
|
||||
throw new AstroError(CspNotEnabled);
|
||||
}
|
||||
renderContext.result?.styleHashes.push(hash);
|
||||
},
|
||||
insertScriptHash(hash) {
|
||||
if (!!pipeline.manifest.csp === false) {
|
||||
throw new AstroError(CspNotEnabled);
|
||||
}
|
||||
renderContext.result?.scriptHashes.push(hash);
|
||||
}
|
||||
};
|
||||
}
|
||||
async createResult(mod) {
|
||||
async createResult(mod, ctx) {
|
||||
const { cookies, pathname, pipeline, routeData, status } = this;
|
||||
const { clientDirectives, inlinedScripts, compressHTML, manifest, renderers, resolve } = pipeline;
|
||||
const { links, scripts, styles } = await pipeline.headElements(routeData);
|
||||
const extraStyleHashes = [];
|
||||
const extraScriptHashes = [];
|
||||
const shouldInjectCspMetaTags = !!manifest.csp;
|
||||
const cspAlgorithm = manifest.csp?.algorithm ?? "SHA-256";
|
||||
if (shouldInjectCspMetaTags) {
|
||||
for (const style of styles) {
|
||||
extraStyleHashes.push(await generateCspDigest(style.children, cspAlgorithm));
|
||||
}
|
||||
for (const script of scripts) {
|
||||
extraScriptHashes.push(await generateCspDigest(script.children, cspAlgorithm));
|
||||
}
|
||||
}
|
||||
const componentMetadata = await pipeline.componentMetadata(routeData) ?? manifest.componentMetadata;
|
||||
const headers = new Headers({ "Content-Type": "text/html" });
|
||||
const partial = typeof this.partial === "boolean" ? this.partial : Boolean(mod.partial);
|
||||
const actionResult = hasActionPayload(this.locals) ? deserializeActionResult(this.locals._actionPayload.actionResult) : void 0;
|
||||
const response = {
|
||||
status,
|
||||
statusText: "OK",
|
||||
status: actionResult?.error ? actionResult?.error.status : status,
|
||||
statusText: actionResult?.error ? actionResult?.error.type : "OK",
|
||||
get headers() {
|
||||
return headers;
|
||||
},
|
||||
@@ -277,9 +406,9 @@ class RenderContext {
|
||||
throw new AstroError(AstroErrorData.AstroResponseHeadersReassigned);
|
||||
}
|
||||
};
|
||||
const actionResult = hasActionPayload(this.locals) ? deserializeActionResult(this.locals._actionPayload.actionResult) : void 0;
|
||||
const result = {
|
||||
base: manifest.base,
|
||||
userAssetsBase: manifest.userAssetsBase,
|
||||
cancelled: false,
|
||||
clientDirectives,
|
||||
inlinedScripts,
|
||||
@@ -287,7 +416,7 @@ class RenderContext {
|
||||
compressHTML,
|
||||
cookies,
|
||||
/** This function returns the `Astro` faux-global */
|
||||
createAstro: (astroGlobal, props, slots) => this.createAstro(result, astroGlobal, props, slots),
|
||||
createAstro: (astroGlobal, props, slots) => this.createAstro(result, astroGlobal, props, slots, ctx),
|
||||
links,
|
||||
params: this.params,
|
||||
partial,
|
||||
@@ -308,10 +437,23 @@ class RenderContext {
|
||||
hasRenderedHead: false,
|
||||
renderedScripts: /* @__PURE__ */ new Set(),
|
||||
hasDirectives: /* @__PURE__ */ new Set(),
|
||||
hasRenderedServerIslandRuntime: false,
|
||||
headInTree: false,
|
||||
extraHead: [],
|
||||
extraStyleHashes,
|
||||
extraScriptHashes,
|
||||
propagators: /* @__PURE__ */ new Set()
|
||||
}
|
||||
},
|
||||
cspDestination: manifest.csp?.cspDestination ?? (routeData.prerender ? "meta" : "header"),
|
||||
shouldInjectCspMetaTags,
|
||||
cspAlgorithm,
|
||||
// The following arrays must be cloned, otherwise they become mutable across routes.
|
||||
scriptHashes: manifest.csp?.scriptHashes ? [...manifest.csp.scriptHashes] : [],
|
||||
scriptResources: manifest.csp?.scriptResources ? [...manifest.csp.scriptResources] : [],
|
||||
styleHashes: manifest.csp?.styleHashes ? [...manifest.csp.styleHashes] : [],
|
||||
styleResources: manifest.csp?.styleResources ? [...manifest.csp.styleResources] : [],
|
||||
directives: manifest.csp?.directives ? [...manifest.csp.directives] : [],
|
||||
isStrictDynamic: manifest.csp?.isStrictDynamic ?? false
|
||||
};
|
||||
return result;
|
||||
}
|
||||
@@ -324,17 +466,19 @@ class RenderContext {
|
||||
*
|
||||
* The page level partial is used as the prototype of the user-visible `Astro` global object, which is instantiated once per use of a component.
|
||||
*/
|
||||
createAstro(result, astroStaticPartial, props, slotValues) {
|
||||
createAstro(result, astroStaticPartial, props, slotValues, apiContext) {
|
||||
let astroPagePartial;
|
||||
if (this.isRewriting) {
|
||||
astroPagePartial = this.#astroPagePartial = this.createAstroPagePartial(
|
||||
result,
|
||||
astroStaticPartial
|
||||
astroStaticPartial,
|
||||
apiContext
|
||||
);
|
||||
} else {
|
||||
astroPagePartial = this.#astroPagePartial ??= this.createAstroPagePartial(
|
||||
result,
|
||||
astroStaticPartial
|
||||
astroStaticPartial,
|
||||
apiContext
|
||||
);
|
||||
}
|
||||
const astroComponentPartial = { props, self: null };
|
||||
@@ -357,7 +501,7 @@ class RenderContext {
|
||||
});
|
||||
return Astro;
|
||||
}
|
||||
createAstroPagePartial(result, astroStaticPartial) {
|
||||
createAstroPagePartial(result, astroStaticPartial, apiContext) {
|
||||
const renderContext = this;
|
||||
const { cookies, locals, params, pipeline, url } = this;
|
||||
const { response } = result;
|
||||
@@ -372,12 +516,32 @@ class RenderContext {
|
||||
const rewrite = async (reroutePayload) => {
|
||||
return await this.#executeRewrite(reroutePayload);
|
||||
};
|
||||
const callAction = createCallAction(apiContext);
|
||||
return {
|
||||
generator: astroStaticPartial.generator,
|
||||
glob: astroStaticPartial.glob,
|
||||
routePattern: this.routeData.route,
|
||||
isPrerendered: this.routeData.prerender,
|
||||
cookies,
|
||||
get session() {
|
||||
if (this.isPrerendered) {
|
||||
pipeline.logger.warn(
|
||||
"session",
|
||||
`Astro.session was used when rendering the route ${green(this.routePattern)}, but it is not available on prerendered pages. If you need access to sessions, make sure that the page is server-rendered using \`export const prerender = false;\` or by setting \`output\` to \`"server"\` in your Astro config to make all your pages server-rendered by default. For more information, see https://docs.astro.build/en/guides/sessions/`
|
||||
);
|
||||
return void 0;
|
||||
}
|
||||
if (!renderContext.session) {
|
||||
pipeline.logger.warn(
|
||||
"session",
|
||||
`Astro.session was used when rendering the route ${green(this.routePattern)}, but no storage configuration was provided. Either configure the storage manually or use an adapter that provides session storage. For more information, see https://docs.astro.build/en/guides/sessions/`
|
||||
);
|
||||
return void 0;
|
||||
}
|
||||
return renderContext.session;
|
||||
},
|
||||
get clientAddress() {
|
||||
return renderContext.clientAddress();
|
||||
return renderContext.getClientAddress();
|
||||
},
|
||||
get currentLocale() {
|
||||
return renderContext.computeCurrentLocale();
|
||||
@@ -397,26 +561,63 @@ class RenderContext {
|
||||
site: pipeline.site,
|
||||
getActionResult: createGetActionResult(locals),
|
||||
get callAction() {
|
||||
return createCallAction(this);
|
||||
return callAction;
|
||||
},
|
||||
url
|
||||
url,
|
||||
get originPathname() {
|
||||
return getOriginPathname(renderContext.request);
|
||||
},
|
||||
insertDirective(payload) {
|
||||
if (!pipeline.manifest.csp) {
|
||||
throw new AstroError(CspNotEnabled);
|
||||
}
|
||||
renderContext.result?.directives.push(payload);
|
||||
},
|
||||
insertScriptResource(resource) {
|
||||
if (!pipeline.manifest.csp) {
|
||||
throw new AstroError(CspNotEnabled);
|
||||
}
|
||||
renderContext.result?.scriptResources.push(resource);
|
||||
},
|
||||
insertStyleResource(resource) {
|
||||
if (!pipeline.manifest.csp) {
|
||||
throw new AstroError(CspNotEnabled);
|
||||
}
|
||||
renderContext.result?.styleResources.push(resource);
|
||||
},
|
||||
insertStyleHash(hash) {
|
||||
if (!pipeline.manifest.csp) {
|
||||
throw new AstroError(CspNotEnabled);
|
||||
}
|
||||
renderContext.result?.styleHashes.push(hash);
|
||||
},
|
||||
insertScriptHash(hash) {
|
||||
if (!!pipeline.manifest.csp === false) {
|
||||
throw new AstroError(CspNotEnabled);
|
||||
}
|
||||
renderContext.result?.scriptHashes.push(hash);
|
||||
}
|
||||
};
|
||||
}
|
||||
clientAddress() {
|
||||
const { pipeline, request } = this;
|
||||
getClientAddress() {
|
||||
const { pipeline, request, routeData, clientAddress } = this;
|
||||
if (routeData.prerender) {
|
||||
throw new AstroError({
|
||||
...AstroErrorData.PrerenderClientAddressNotAvailable,
|
||||
message: AstroErrorData.PrerenderClientAddressNotAvailable.message(routeData.component)
|
||||
});
|
||||
}
|
||||
if (clientAddress) {
|
||||
return clientAddress;
|
||||
}
|
||||
if (clientAddressSymbol in request) {
|
||||
return Reflect.get(request, clientAddressSymbol);
|
||||
}
|
||||
if (pipeline.serverLike) {
|
||||
if (request.body === null) {
|
||||
throw new AstroError(AstroErrorData.PrerenderClientAddressNotAvailable);
|
||||
}
|
||||
if (pipeline.adapterName) {
|
||||
throw new AstroError({
|
||||
...AstroErrorData.ClientAddressNotAvailable,
|
||||
message: AstroErrorData.ClientAddressNotAvailable.message(pipeline.adapterName)
|
||||
});
|
||||
}
|
||||
if (pipeline.adapterName) {
|
||||
throw new AstroError({
|
||||
...AstroErrorData.ClientAddressNotAvailable,
|
||||
message: AstroErrorData.ClientAddressNotAvailable.message(pipeline.adapterName)
|
||||
});
|
||||
}
|
||||
throw new AstroError(AstroErrorData.StaticClientAddressNotAvailable);
|
||||
}
|
||||
@@ -438,8 +639,27 @@ class RenderContext {
|
||||
return this.#currentLocale;
|
||||
}
|
||||
let computedLocale;
|
||||
const pathname = routeData.pathname && !isRoute404or500(routeData) ? routeData.pathname : url.pathname;
|
||||
computedLocale = computeCurrentLocale(pathname, locales, defaultLocale);
|
||||
if (isRouteServerIsland(routeData)) {
|
||||
let referer = this.request.headers.get("referer");
|
||||
if (referer) {
|
||||
if (URL.canParse(referer)) {
|
||||
referer = new URL(referer).pathname;
|
||||
}
|
||||
computedLocale = computeCurrentLocale(referer, locales, defaultLocale);
|
||||
}
|
||||
} else {
|
||||
let pathname = routeData.pathname;
|
||||
if (!routeData.pattern.test(url.pathname)) {
|
||||
for (const fallbackRoute of routeData.fallbackRoutes) {
|
||||
if (fallbackRoute.pattern.test(url.pathname)) {
|
||||
pathname = fallbackRoute.pathname;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
pathname = pathname && !isRoute404or500(routeData) ? pathname : url.pathname;
|
||||
computedLocale = computeCurrentLocale(pathname, locales, defaultLocale);
|
||||
}
|
||||
this.#currentLocale = computedLocale ?? fallbackTo;
|
||||
return this.#currentLocale;
|
||||
}
|
||||
|
Reference in New Issue
Block a user