${statusCode ? `${statusCode}: ` : ""}${title}
${body || `Path: ${escape(pathname)}
`}
Path: ${escape(pathname)}
`}
", "
", "",
"",
// Common whitespace
" ",
"\n"
];
function matchesLevel(messageLevel, configuredLevel) {
return levels[messageLevel] >= levels[configuredLevel];
}
function nodeLogDestination(config = {}) {
const { level = "info" } = config;
return {
write(event) {
let dest = process.stderr;
if (levels[event.level] < levels["error"]) {
dest = process.stdout;
}
if (!matchesLevel(event.level, level)) {
return;
}
let trailingLine = event.newLine ? "\n" : "";
if (event.label === "SKIP_FORMAT") {
dest.write(event.message + trailingLine);
} else {
dest.write(getEventPrefix(event) + " " + event.message + trailingLine);
}
}
};
}
function node_default(options) {
return nodeLogDestination(options);
}
function consoleLogDestination(config = {}) {
const { level = "info" } = config;
return {
write(event) {
let dest = console.error;
if (levels[event.level] < levels["error"]) {
dest = console.info;
}
if (!matchesLevel(event.level, level)) {
return;
}
if (event.label === "SKIP_FORMAT") {
dest(event.message);
} else {
dest(getEventPrefix(event) + " " + event.message);
}
}
};
}
function createConsoleLogger({ level }) {
return new AstroLogger({
level,
destination: consoleLogDestination()
});
}
function console_default(options) {
return consoleLogDestination(options);
}
const SGR_REGEX = new RegExp(`${String.fromCharCode(27)}\\[[0-9;]*m`, "g");
function jsonLoggerDestination(config = {}) {
const { pretty = false, level = "info" } = config;
return {
write(event) {
let dest = process.stderr;
if (levels[event.level] < levels["error"]) {
dest = process.stdout;
}
if (!matchesLevel(event.level, level)) {
return;
}
let trailingLine = event.newLine ? "\n" : "";
const message = event.message.replace(SGR_REGEX, "");
if (pretty) {
dest.write(
JSON.stringify({ message, label: event.label, level: event.level }, null, 2) + trailingLine
);
} else {
dest.write(
JSON.stringify({ message, label: event.label, level: event.level }) + trailingLine
);
}
}
};
}
function compose(destinations) {
return {
write(chunk) {
for (const logger of destinations) {
logger.write(chunk);
}
},
flush() {
for (const logger of destinations) {
if (logger.flush) {
logger.flush();
}
}
},
close() {
for (const logger of destinations) {
if (logger.close) {
logger.close();
}
}
}
};
}
async function loadLogger(config, level = "info") {
let cause = void 0;
try {
switch (config.entrypoint) {
case "astro/logger/node": {
return new AstroLogger({
destination: node_default(config.config),
level
});
}
case "astro/logger/console": {
return new AstroLogger({
destination: console_default(config.config),
level
});
}
case "astro/logger/json": {
return new AstroLogger({
destination: jsonLoggerDestination(config.config),
level
});
}
case "astro/logger/compose": {
let destinations = [];
if (config.config?.loggers) {
const loggers = config.config?.loggers;
destinations = await Promise.all(
loggers.map(async (loggerConfig) => {
const logger = await import(
/* @vite-ignore */
loggerConfig.entrypoint
);
return logger.default(loggerConfig.config);
})
);
}
return new AstroLogger({
destination: compose(destinations),
level
});
}
default: {
const nodeLogger = await import(
/* @vite-ignore */
config.entrypoint
);
return new AstroLogger({
destination: nodeLogger.default(config.config),
level
});
}
}
} catch (e) {
if (e instanceof Error) {
cause = e;
}
}
const error = new AstroError({
...UnableToLoadLogger,
message: UnableToLoadLogger.message(config.entrypoint)
});
if (cause) {
error.cause = cause;
}
throw error;
}
class Pipeline {
internalMiddleware;
resolvedMiddleware = void 0;
resolvedLogger = false;
resolvedActions = void 0;
resolvedSessionDriver = void 0;
resolvedCacheProvider = void 0;
compiledCacheRoutes = void 0;
nodePool;
htmlStringCache;
logger;
manifest;
/**
* "development" or "production" only
*/
runtimeMode;
renderers;
resolve;
streaming;
/**
* Used to provide better error messages for `Astro.clientAddress`
*/
adapterName;
clientDirectives;
inlinedScripts;
compressHTML;
i18n;
middleware;
routeCache;
/**
* Used for `Astro.site`.
*/
site;
/**
* Array of built-in, internal, routes.
* Used to find the route module
*/
defaultRoutes;
actions;
sessionDriver;
cacheProvider;
cacheConfig;
serverIslands;
constructor(logger, manifest, runtimeMode, renderers, resolve, streaming, adapterName = manifest.adapterName, clientDirectives = manifest.clientDirectives, inlinedScripts = manifest.inlinedScripts, compressHTML = manifest.compressHTML, i18n = manifest.i18n, middleware = manifest.middleware, routeCache = new RouteCache(logger, runtimeMode), site = manifest.site ? new URL(manifest.site) : void 0, defaultRoutes = createDefaultRoutes(manifest), actions = manifest.actions, sessionDriver = manifest.sessionDriver, cacheProvider = manifest.cacheProvider, cacheConfig = manifest.cacheConfig, serverIslands = manifest.serverIslandMappings) {
this.logger = logger;
this.manifest = manifest;
this.runtimeMode = runtimeMode;
this.renderers = renderers;
this.resolve = resolve;
this.streaming = streaming;
this.adapterName = adapterName;
this.clientDirectives = clientDirectives;
this.inlinedScripts = inlinedScripts;
this.compressHTML = compressHTML;
this.i18n = i18n;
this.middleware = middleware;
this.routeCache = routeCache;
this.site = site;
this.defaultRoutes = defaultRoutes;
this.actions = actions;
this.sessionDriver = sessionDriver;
this.cacheProvider = cacheProvider;
this.cacheConfig = cacheConfig;
this.serverIslands = serverIslands;
this.internalMiddleware = [];
if (i18n?.strategy !== "manual") {
this.internalMiddleware.push(
createI18nMiddleware(i18n, manifest.base, manifest.trailingSlash, manifest.buildFormat)
);
}
if (manifest.experimentalQueuedRendering.enabled) {
this.nodePool = this.createNodePool(
manifest.experimentalQueuedRendering.poolSize ?? 1e3,
false
);
if (manifest.experimentalQueuedRendering.contentCache) {
this.htmlStringCache = this.createStringCache();
}
}
}
/**
* Resolves the middleware from the manifest, and returns the `onRequest` function. If `onRequest` isn't there,
* it returns a no-op function
*/
async getMiddleware() {
if (this.resolvedMiddleware) {
return this.resolvedMiddleware;
}
if (this.middleware) {
const middlewareInstance = await this.middleware();
const onRequest = middlewareInstance.onRequest ?? NOOP_MIDDLEWARE_FN;
const internalMiddlewares = [onRequest];
if (this.manifest.checkOrigin) {
internalMiddlewares.unshift(createOriginCheckMiddleware());
}
this.resolvedMiddleware = sequence(...internalMiddlewares);
return this.resolvedMiddleware;
} else {
this.resolvedMiddleware = NOOP_MIDDLEWARE_FN;
return this.resolvedMiddleware;
}
}
/**
* Clears the cached middleware so it is re-resolved on the next request.
* Called via HMR when middleware files change during development.
*/
clearMiddleware() {
this.resolvedMiddleware = void 0;
}
/**
* Resolves the logger destination from the manifest and updates the pipeline logger.
* If the user configured `experimental.logger`, the bundled logger factory is loaded
* and replaces the default console destination. This is lazy and only resolves once.
*/
async getLogger() {
if (this.resolvedLogger) {
return this.logger;
}
this.resolvedLogger = true;
if (this.manifest.experimentalLogger) {
this.logger = await loadLogger(this.manifest.experimentalLogger);
}
return this.logger;
}
async getActions() {
if (this.resolvedActions) {
return this.resolvedActions;
} else if (this.actions) {
return this.actions();
}
return NOOP_ACTIONS_MOD;
}
async getSessionDriver() {
if (this.resolvedSessionDriver !== void 0) {
return this.resolvedSessionDriver;
}
if (this.sessionDriver) {
const driverModule = await this.sessionDriver();
this.resolvedSessionDriver = driverModule?.default || null;
return this.resolvedSessionDriver;
}
this.resolvedSessionDriver = null;
return null;
}
async getCacheProvider() {
if (this.resolvedCacheProvider !== void 0) {
return this.resolvedCacheProvider;
}
if (this.cacheProvider) {
const mod = await this.cacheProvider();
const factory = mod?.default || null;
this.resolvedCacheProvider = factory ? factory(this.cacheConfig?.options) : null;
return this.resolvedCacheProvider;
}
this.resolvedCacheProvider = null;
return null;
}
async getServerIslands() {
if (this.serverIslands) {
return this.serverIslands();
}
return {
serverIslandMap: /* @__PURE__ */ new Map(),
serverIslandNameMap: /* @__PURE__ */ new Map()
};
}
async getAction(path) {
const pathKeys = path.split(".").map((key) => decodeURIComponent(key));
let { server } = await this.getActions();
if (!server || !(typeof server === "object")) {
throw new TypeError(
`Expected \`server\` export in actions file to be an object. Received ${typeof server}.`
);
}
for (const key of pathKeys) {
if (FORBIDDEN_PATH_KEYS.has(key)) {
throw new AstroError({
...ActionNotFoundError,
message: ActionNotFoundError.message(pathKeys.join("."))
});
}
if (!Object.hasOwn(server, key)) {
throw new AstroError({
...ActionNotFoundError,
message: ActionNotFoundError.message(pathKeys.join("."))
});
}
server = server[key];
}
if (typeof server !== "function") {
throw new TypeError(
`Expected handler for action ${pathKeys.join(".")} to be a function. Received ${typeof server}.`
);
}
return server;
}
async getModuleForRoute(route) {
for (const defaultRoute of this.defaultRoutes) {
if (route.component === defaultRoute.component) {
return {
page: () => Promise.resolve(defaultRoute.instance)
};
}
}
if (route.type === "redirect") {
return RedirectSinglePageBuiltModule;
} else {
if (this.manifest.pageMap) {
const importComponentInstance = this.manifest.pageMap.get(route.component);
if (!importComponentInstance) {
throw new Error(
`Unexpectedly unable to find a component instance for route ${route.route}`
);
}
return await importComponentInstance();
} else if (this.manifest.pageModule) {
return this.manifest.pageModule;
}
throw new Error(
"Astro couldn't find the correct page to render, probably because it wasn't correctly mapped for SSR usage. This is an internal error, please file an issue."
);
}
}
createNodePool(poolSize, stats) {
return new NodePool(poolSize, stats);
}
createStringCache() {
return new HTMLStringCache(1e3);
}
}
function routeIsRedirect(route) {
return route?.type === "redirect";
}
function routeIsFallback(route) {
return route?.type === "fallback";
}
function getFallbackRoute(route, routeList) {
const fallbackRoute = routeList.find((r) => {
if (route.route === "/" && r.routeData.route === "/") {
return true;
}
return r.routeData.fallbackRoutes.find((f) => {
return f.route === route.route;
});
});
if (!fallbackRoute) {
throw new Error(`No fallback route found for route ${route.route}`);
}
return fallbackRoute.routeData;
}
function routeHasHtmlExtension(route) {
return route.segments.some(
(segment) => segment.some((part) => !part.dynamic && part.content.includes(".html"))
);
}
async function getProps(opts) {
const {
logger,
mod,
routeData: route,
routeCache,
pathname,
serverLike,
base,
trailingSlash
} = opts;
if (!route || route.pathname) {
return {};
}
if (routeIsRedirect(route) || routeIsFallback(route) || route.component === DEFAULT_404_COMPONENT) {
return {};
}
const staticPaths = await callGetStaticPaths({
mod,
route,
routeCache,
ssr: serverLike,
base,
trailingSlash
});
const params = getParams(route, pathname);
const matchedStaticPath = findPathItemByKey(staticPaths, params, route, logger, trailingSlash);
if (!matchedStaticPath && (serverLike ? route.prerender : true)) {
throw new AstroError({
...NoMatchingStaticPathFound,
message: NoMatchingStaticPathFound.message(pathname),
hint: NoMatchingStaticPathFound.hint([route.component])
});
}
if (mod) {
validatePrerenderEndpointCollision(route, mod, params);
}
const props = matchedStaticPath?.props ? { ...matchedStaticPath.props } : {};
return props;
}
function getParams(route, pathname) {
if (!route.params.length) return {};
const path = pathname.endsWith(".html") && !routeHasHtmlExtension(route) ? pathname.slice(0, -5) : pathname;
const allPatterns = [route, ...route.fallbackRoutes].map((r) => r.pattern);
const paramsMatch = allPatterns.map((pattern) => pattern.exec(path)).find((x) => x);
if (!paramsMatch) return {};
const params = {};
route.params.forEach((key, i) => {
if (key.startsWith("...")) {
params[key.slice(3)] = paramsMatch[i + 1] ? paramsMatch[i + 1] : void 0;
} else {
params[key] = paramsMatch[i + 1];
}
});
return params;
}
function validatePrerenderEndpointCollision(route, mod, params) {
if (route.type === "endpoint" && mod.getStaticPaths) {
const lastSegment = route.segments[route.segments.length - 1];
const paramValues = Object.values(params);
const lastParam = paramValues[paramValues.length - 1];
if (lastSegment.length === 1 && lastSegment[0].dynamic && lastParam === void 0) {
throw new AstroError({
...PrerenderDynamicEndpointPathCollide,
message: PrerenderDynamicEndpointPathCollide.message(route.route),
hint: PrerenderDynamicEndpointPathCollide.hint(route.component),
location: {
file: route.component
}
});
}
}
}
function getFunctionExpression(slot) {
if (!slot) return;
const expressions = slot?.expressions?.filter((e) => isRenderInstruction(e) === false);
if (expressions?.length !== 1) return;
return expressions[0];
}
class Slots {
#result;
#slots;
#logger;
constructor(result, slots, logger) {
this.#result = result;
this.#slots = slots;
this.#logger = logger;
if (slots) {
for (const key of Object.keys(slots)) {
if (this[key] !== void 0) {
throw new AstroError({
...ReservedSlotName,
message: ReservedSlotName.message(key)
});
}
Object.defineProperty(this, key, {
get() {
return true;
},
enumerable: true
});
}
}
}
has(name) {
if (!this.#slots) return false;
return Boolean(this.#slots[name]);
}
async render(name, args = []) {
if (!this.#slots || !this.has(name)) return;
const result = this.#result;
if (!Array.isArray(args)) {
this.#logger.warn(
null,
`Expected second parameter to be an array, received a ${typeof args}. If you're trying to pass an array as a single argument and getting unexpected results, make sure you're passing your array as an item of an array. Ex: Astro.slots.render('default', [["Hello", "World"]])`
);
} else if (args.length > 0) {
const slotValue = this.#slots[name];
const component = typeof slotValue === "function" ? await slotValue(result) : await slotValue;
const expression = getFunctionExpression(component);
if (expression) {
const slot = async () => typeof expression === "function" ? expression(...args) : expression;
return await renderSlotToString(result, slot).then((res) => {
return res;
});
}
if (typeof component === "function") {
return await renderJSX(result, component(...args)).then(
(res) => res != null ? String(res) : res
);
}
}
const content = await renderSlotToString(result, this.#slots[name]);
const outHTML = chunkToString(result, content);
return outHTML;
}
}
function sequence(...handlers) {
const filtered = handlers.filter((h) => !!h);
const length = filtered.length;
if (!length) {
return defineMiddleware((_context, next) => {
return next();
});
}
return defineMiddleware((context, next) => {
let carriedPayload = void 0;
return applyHandle(0, context);
function applyHandle(i, handleContext) {
const handle = filtered[i];
const result = handle(handleContext, async (payload) => {
if (i < length - 1) {
if (payload) {
let newRequest;
if (payload instanceof Request) {
newRequest = payload;
} else if (payload instanceof URL) {
newRequest = new Request(payload, handleContext.request.clone());
} else {
newRequest = new Request(
new URL(payload, handleContext.url.origin),
handleContext.request.clone()
);
}
const oldPathname = handleContext.url.pathname;
const pipeline = Reflect.get(handleContext, pipelineSymbol);
const { routeData, pathname } = await pipeline.tryRewrite(
payload,
handleContext.request
);
if (pipeline.manifest.serverLike === true && handleContext.isPrerendered === false && routeData.prerender === true) {
throw new AstroError({
...ForbiddenRewrite,
message: ForbiddenRewrite.message(
handleContext.url.pathname,
pathname,
routeData.component
),
hint: ForbiddenRewrite.hint(routeData.component)
});
}
carriedPayload = payload;
handleContext.request = newRequest;
handleContext.url = new URL(newRequest.url);
handleContext.params = getParams(routeData, pathname);
handleContext.routePattern = routeData.route;
setOriginPathname(
handleContext.request,
oldPathname,
pipeline.manifest.trailingSlash,
pipeline.manifest.buildFormat
);
}
return applyHandle(i + 1, handleContext);
} else {
return next(payload ?? carriedPayload);
}
});
return result;
}
});
}
function isExternalURL(url) {
return url.startsWith("http://") || url.startsWith("https://") || url.startsWith("//");
}
function redirectIsExternal(redirect) {
if (typeof redirect === "string") {
return isExternalURL(redirect);
} else {
return isExternalURL(redirect.destination);
}
}
function computeRedirectStatus(method, redirect, redirectRoute) {
return redirectRoute && typeof redirect === "object" ? redirect.status : method === "GET" ? 301 : 308;
}
function resolveRedirectTarget(params, redirect, redirectRoute, trailingSlash) {
if (typeof redirectRoute !== "undefined") {
const generate = getRouteGenerator(redirectRoute.segments, trailingSlash);
return generate(params);
} else if (typeof redirect === "string") {
if (redirectIsExternal(redirect)) {
return redirect;
} else {
let target = redirect;
for (const param of Object.keys(params)) {
const paramValue = params[param];
target = target.replace(`[${param}]`, paramValue).replace(`[...${param}]`, paramValue);
}
return target;
}
} else if (typeof redirect === "undefined") {
return "/";
}
return redirect.destination;
}
async function renderRedirect(renderContext) {
const {
request: { method },
routeData
} = renderContext;
const { redirect, redirectRoute } = routeData;
const status = computeRedirectStatus(method, redirect, redirectRoute);
const headers = {
location: encodeURI(
resolveRedirectTarget(
renderContext.params,
redirect,
redirectRoute,
renderContext.pipeline.manifest.trailingSlash
)
)
};
if (redirect && redirectIsExternal(redirect)) {
if (typeof redirect === "string") {
return Response.redirect(redirect, status);
} else {
return Response.redirect(redirect.destination, status);
}
}
return new Response(null, { status, headers });
}
function matchRoute(pathname, manifest) {
if (isRoute404(pathname)) {
const errorRoute = manifest.routes.find((route) => isRoute404(route.route));
if (errorRoute) return errorRoute;
}
if (isRoute500(pathname)) {
const errorRoute = manifest.routes.find((route) => isRoute500(route.route));
if (errorRoute) return errorRoute;
}
return manifest.routes.find((route) => {
return route.pattern.test(pathname) || route.fallbackRoutes.some((fallbackRoute) => fallbackRoute.pattern.test(pathname));
});
}
function isRoute404or500(route) {
return isRoute404(route.route) || isRoute500(route.route);
}
function isRouteServerIsland(route) {
return route.component === SERVER_ISLAND_COMPONENT;
}
function isRouteExternalRedirect(route) {
return !!(route.type === "redirect" && route.redirect && redirectIsExternal(route.redirect));
}
function defaultSetHeaders(options) {
const headers = new Headers();
const directives = [];
if (options.maxAge !== void 0) {
directives.push(`max-age=${options.maxAge}`);
}
if (options.swr !== void 0) {
directives.push(`stale-while-revalidate=${options.swr}`);
}
if (directives.length > 0) {
headers.set("CDN-Cache-Control", directives.join(", "));
}
if (options.tags && options.tags.length > 0) {
headers.set("Cache-Tag", options.tags.join(", "));
}
if (options.lastModified) {
headers.set("Last-Modified", options.lastModified.toUTCString());
}
if (options.etag) {
headers.set("ETag", options.etag);
}
return headers;
}
function isLiveDataEntry(value) {
return value != null && typeof value === "object" && "id" in value && "data" in value && "cacheHint" in value;
}
const APPLY_HEADERS = /* @__PURE__ */ Symbol.for("astro:cache:apply");
const IS_ACTIVE = /* @__PURE__ */ Symbol.for("astro:cache:active");
class AstroCache {
#options = {};
#tags = /* @__PURE__ */ new Set();
#disabled = false;
#provider;
enabled = true;
constructor(provider) {
this.#provider = provider;
}
set(input) {
if (input === false) {
this.#disabled = true;
this.#tags.clear();
this.#options = {};
return;
}
this.#disabled = false;
let options;
if (isLiveDataEntry(input)) {
if (!input.cacheHint) return;
options = input.cacheHint;
} else {
options = input;
}
if ("maxAge" in options && options.maxAge !== void 0) this.#options.maxAge = options.maxAge;
if ("swr" in options && options.swr !== void 0)
this.#options.swr = options.swr;
if ("etag" in options && options.etag !== void 0)
this.#options.etag = options.etag;
if (options.lastModified !== void 0) {
if (!this.#options.lastModified || options.lastModified > this.#options.lastModified) {
this.#options.lastModified = options.lastModified;
}
}
if (options.tags) {
for (const tag of options.tags) this.#tags.add(tag);
}
}
get tags() {
return [...this.#tags];
}
/**
* Get the current cache options (read-only snapshot).
* Includes all accumulated options: maxAge, swr, tags, etag, lastModified.
*/
get options() {
return {
...this.#options,
tags: this.tags
};
}
async invalidate(input) {
if (!this.#provider) {
throw new AstroError(CacheNotEnabled);
}
let options;
if (isLiveDataEntry(input)) {
options = { tags: input.cacheHint?.tags ?? [] };
} else {
options = input;
}
return this.#provider.invalidate(options);
}
/** @internal */
[APPLY_HEADERS](response) {
if (this.#disabled) return;
const finalOptions = { ...this.#options, tags: this.tags };
if (finalOptions.maxAge === void 0 && !finalOptions.tags?.length) return;
const headers = this.#provider?.setHeaders?.(finalOptions) ?? defaultSetHeaders(finalOptions);
for (const [key, value] of headers) {
response.headers.set(key, value);
}
}
/** @internal */
get [IS_ACTIVE]() {
return !this.#disabled && (this.#options.maxAge !== void 0 || this.#tags.size > 0);
}
}
function applyCacheHeaders(cache, response) {
if (APPLY_HEADERS in cache) {
cache[APPLY_HEADERS](response);
}
}
const ROUTE_DYNAMIC_SPLIT = /\[(.+?\(.+?\)|.+?)\]/;
const ROUTE_SPREAD = /^\.{3}.+$/;
function getParts(part, file) {
const result = [];
part.split(ROUTE_DYNAMIC_SPLIT).map((str, i) => {
if (!str) return;
const dynamic = i % 2 === 1;
const [, content] = dynamic ? /([^(]+)$/.exec(str) || [null, null] : [null, str];
if (!content || dynamic && !/^(?:\.\.\.)?[\w$]+$/.test(content)) {
throw new Error(`Invalid route ${file} \u2014 parameter name must match /^[a-zA-Z0-9_$]+$/`);
}
result.push({
content,
dynamic,
spread: dynamic && ROUTE_SPREAD.test(content)
});
});
return result;
}
function routeComparator(a, b) {
const commonLength = Math.min(a.segments.length, b.segments.length);
for (let index = 0; index < commonLength; index++) {
const aSegment = a.segments[index];
const bSegment = b.segments[index];
const aIsStatic = aSegment.every((part) => !part.dynamic && !part.spread);
const bIsStatic = bSegment.every((part) => !part.dynamic && !part.spread);
if (aIsStatic && bIsStatic) {
const aContent = aSegment.map((part) => part.content).join("");
const bContent = bSegment.map((part) => part.content).join("");
if (aContent !== bContent) {
return aContent.localeCompare(bContent);
}
}
if (aIsStatic !== bIsStatic) {
return aIsStatic ? -1 : 1;
}
const aAllDynamic = aSegment.every((part) => part.dynamic);
const bAllDynamic = bSegment.every((part) => part.dynamic);
if (aAllDynamic !== bAllDynamic) {
return aAllDynamic ? 1 : -1;
}
const aHasSpread = aSegment.some((part) => part.spread);
const bHasSpread = bSegment.some((part) => part.spread);
if (aHasSpread !== bHasSpread) {
return aHasSpread ? 1 : -1;
}
}
const aLength = a.segments.length;
const bLength = b.segments.length;
if (aLength !== bLength) {
const aEndsInRest = a.segments.at(-1)?.some((part) => part.spread);
const bEndsInRest = b.segments.at(-1)?.some((part) => part.spread);
if (aEndsInRest !== bEndsInRest && Math.abs(aLength - bLength) === 1) {
if (aLength > bLength && aEndsInRest) {
return 1;
}
if (bLength > aLength && bEndsInRest) {
return -1;
}
}
return aLength > bLength ? -1 : 1;
}
if (a.type === "endpoint" !== (b.type === "endpoint")) {
return a.type === "endpoint" ? -1 : 1;
}
return a.route.localeCompare(b.route);
}
function compileCacheRoutes(routes, base, trailingSlash) {
const compiled = Object.entries(routes).map(([path, options]) => {
const segments = removeLeadingForwardSlash(path).split("/").filter(Boolean).map((s) => getParts(s, path));
const pattern = getPattern(segments, base, trailingSlash);
return { pattern, options, segments, route: path };
});
compiled.sort(
(a, b) => routeComparator(
{ segments: a.segments, route: a.route, type: "page" },
{ segments: b.segments, route: b.route, type: "page" }
)
);
return compiled;
}
function matchCacheRoute(pathname, compiledRoutes) {
for (const route of compiledRoutes) {
if (route.pattern.test(pathname)) return route.options;
}
return null;
}
const PERSIST_SYMBOL = /* @__PURE__ */ Symbol();
const DEFAULT_COOKIE_NAME = "astro-session";
const VALID_COOKIE_REGEX = /^[\w-]+$/;
const unflatten = (parsed, _) => {
return unflatten$1(parsed, {
URL: (href) => new URL(href)
});
};
const stringify = (data, _) => {
return stringify$1(data, {
// Support URL objects
URL: (val) => val instanceof URL && val.href
});
};
class AstroSession {
// The cookies object.
#cookies;
// The session configuration.
#config;
// The cookie config
#cookieConfig;
// The cookie name
#cookieName;
// The unstorage object for the session driver.
#storage;
#data;
// The session ID. A v4 UUID.
#sessionID;
// Sessions to destroy. Needed because we won't have the old session ID after it's destroyed locally.
#toDestroy = /* @__PURE__ */ new Set();
// Session keys to delete. Used for partial data sets to avoid overwriting the deleted value.
#toDelete = /* @__PURE__ */ new Set();
// Whether the session is dirty and needs to be saved.
#dirty = false;
// Whether the session cookie has been set.
#cookieSet = false;
// Whether the session ID was sourced from a client cookie rather than freshly generated.
#sessionIDFromCookie = false;
// The local data is "partial" if it has not been loaded from storage yet and only
// contains values that have been set or deleted in-memory locally.
// We do this to avoid the need to block on loading data when it is only being set.
// When we load the data from storage, we need to merge it with the local partial data,
// preserving in-memory changes and deletions.
#partial = true;
// The driver factory function provided by the pipeline
#driverFactory;
static #sharedStorage = /* @__PURE__ */ new Map();
constructor({
cookies,
config,
runtimeMode,
driverFactory,
mockStorage
}) {
if (!config) {
throw new AstroError({
...SessionStorageInitError,
message: SessionStorageInitError.message(
"No driver was defined in the session configuration and the adapter did not provide a default driver."
)
});
}
this.#cookies = cookies;
this.#driverFactory = driverFactory;
const { cookie: cookieConfig = DEFAULT_COOKIE_NAME, ...configRest } = config;
let cookieConfigObject;
if (typeof cookieConfig === "object") {
const { name = DEFAULT_COOKIE_NAME, ...rest } = cookieConfig;
this.#cookieName = name;
cookieConfigObject = rest;
} else {
this.#cookieName = cookieConfig || DEFAULT_COOKIE_NAME;
}
this.#cookieConfig = {
sameSite: "lax",
secure: runtimeMode === "production",
path: "/",
...cookieConfigObject,
httpOnly: true
};
this.#config = configRest;
if (mockStorage) {
this.#storage = mockStorage;
}
}
/**
* Gets a session value. Returns `undefined` if the session or value does not exist.
*/
async get(key) {
return (await this.#ensureData()).get(key)?.data;
}
/**
* Checks if a session value exists.
*/
async has(key) {
return (await this.#ensureData()).has(key);
}
/**
* Gets all session values.
*/
async keys() {
return (await this.#ensureData()).keys();
}
/**
* Gets all session values.
*/
async values() {
return [...(await this.#ensureData()).values()].map((entry) => entry.data);
}
/**
* Gets all session entries.
*/
async entries() {
return [...(await this.#ensureData()).entries()].map(([key, entry]) => [key, entry.data]);
}
/**
* Deletes a session value.
*/
delete(key) {
this.#data?.delete(key);
if (this.#partial) {
this.#toDelete.add(key);
}
this.#dirty = true;
}
/**
* Sets a session value. The session is created if it does not exist.
*/
set(key, value, { ttl } = {}) {
if (!key) {
throw new AstroError({
...SessionStorageSaveError,
message: "The session key was not provided."
});
}
let cloned;
try {
cloned = unflatten(JSON.parse(stringify(value)));
} catch (err) {
throw new AstroError(
{
...SessionStorageSaveError,
message: `The session data for ${key} could not be serialized.`,
hint: "See the devalue library for all supported types: https://github.com/rich-harris/devalue"
},
{ cause: err }
);
}
if (!this.#cookieSet) {
this.#setCookie();
this.#cookieSet = true;
}
this.#data ??= /* @__PURE__ */ new Map();
const lifetime = ttl ?? this.#config.ttl;
const expires = typeof lifetime === "number" ? Date.now() + lifetime * 1e3 : lifetime;
this.#data.set(key, {
data: cloned,
expires
});
this.#dirty = true;
}
/**
* Destroys the session, clearing the cookie and storage if it exists.
*/
destroy() {
const sessionId = this.#sessionID ?? this.#cookies.get(this.#cookieName)?.value;
if (sessionId) {
this.#toDestroy.add(sessionId);
}
this.#cookies.delete(this.#cookieName, this.#cookieConfig);
this.#sessionID = void 0;
this.#data = void 0;
this.#dirty = true;
}
/**
* Regenerates the session, creating a new session ID. The existing session data is preserved.
*/
async regenerate() {
let data = /* @__PURE__ */ new Map();
try {
data = await this.#ensureData();
} catch (err) {
console.error("Failed to load session data during regeneration:", err);
}
const oldSessionId = this.#sessionID;
this.#sessionID = crypto.randomUUID();
this.#sessionIDFromCookie = false;
this.#data = data;
this.#dirty = true;
await this.#setCookie();
if (oldSessionId && this.#storage) {
this.#storage.removeItem(oldSessionId).catch((err) => {
console.error("Failed to remove old session data:", err);
});
}
}
// Persists the session data to storage.
// This is called automatically at the end of the request.
// Uses a symbol to prevent users from calling it directly.
async [PERSIST_SYMBOL]() {
if (!this.#dirty && !this.#toDestroy.size) {
return;
}
const storage = await this.#ensureStorage();
if (this.#dirty && this.#data) {
const data = await this.#ensureData();
this.#toDelete.forEach((key2) => data.delete(key2));
const key = this.#ensureSessionID();
let serialized;
try {
serialized = stringify(data);
} catch (err) {
throw new AstroError(
{
...SessionStorageSaveError,
message: SessionStorageSaveError.message(
"The session data could not be serialized.",
this.#config.driver
)
},
{ cause: err }
);
}
await storage.setItem(key, serialized);
this.#dirty = false;
}
if (this.#toDestroy.size > 0) {
const cleanupPromises = [...this.#toDestroy].map(
(sessionId) => storage.removeItem(sessionId).catch((err) => {
console.error("Failed to clean up session %s:", sessionId, err);
})
);
await Promise.all(cleanupPromises);
this.#toDestroy.clear();
}
}
get sessionID() {
return this.#sessionID;
}
/**
* Loads a session from storage with the given ID, and replaces the current session.
* Any changes made to the current session will be lost.
* This is not normally needed, as the session is automatically loaded using the cookie.
* However it can be used to restore a session where the ID has been recorded somewhere
* else (e.g. in a database).
*/
async load(sessionID) {
this.#sessionID = sessionID;
this.#data = void 0;
await this.#setCookie();
await this.#ensureData();
}
/**
* Sets the session cookie.
*/
async #setCookie() {
if (!VALID_COOKIE_REGEX.test(this.#cookieName)) {
throw new AstroError({
...SessionStorageSaveError,
message: "Invalid cookie name. Cookie names can only contain letters, numbers, and dashes."
});
}
const value = this.#ensureSessionID();
this.#cookies.set(this.#cookieName, value, this.#cookieConfig);
}
/**
* Attempts to load the session data from storage, or creates a new data object if none exists.
* If there is existing partial data, it will be merged into the new data object.
*/
async #ensureData() {
const storage = await this.#ensureStorage();
if (this.#data && !this.#partial) {
return this.#data;
}
this.#data ??= /* @__PURE__ */ new Map();
const raw = await storage.get(this.#ensureSessionID());
if (!raw) {
if (this.#sessionIDFromCookie) {
this.#sessionID = crypto.randomUUID();
this.#sessionIDFromCookie = false;
if (this.#cookieSet) {
await this.#setCookie();
}
}
return this.#data;
}
try {
const storedMap = unflatten(raw);
if (!(storedMap instanceof Map)) {
await this.destroy();
throw new AstroError({
...SessionStorageInitError,
message: SessionStorageInitError.message(
"The session data was an invalid type.",
this.#config.driver
)
});
}
const now = Date.now();
for (const [key, value] of storedMap) {
const expired = typeof value.expires === "number" && value.expires < now;
if (!this.#data.has(key) && !this.#toDelete.has(key) && !expired) {
this.#data.set(key, value);
}
}
this.#partial = false;
return this.#data;
} catch (err) {
await this.destroy();
if (err instanceof AstroError) {
throw err;
}
throw new AstroError(
{
...SessionStorageInitError,
message: SessionStorageInitError.message(
"The session data could not be parsed.",
this.#config.driver
)
},
{ cause: err }
);
}
}
/**
* Returns the session ID, generating a new one if it does not exist.
*/
#ensureSessionID() {
if (!this.#sessionID) {
const cookieValue = this.#cookies.get(this.#cookieName)?.value;
if (cookieValue) {
this.#sessionID = cookieValue;
this.#sessionIDFromCookie = true;
} else {
this.#sessionID = crypto.randomUUID();
}
}
return this.#sessionID;
}
/**
* Ensures the storage is initialized.
* This is called automatically when a storage operation is needed.
*/
async #ensureStorage() {
if (this.#storage) {
return this.#storage;
}
if (AstroSession.#sharedStorage.has(this.#config.driver)) {
this.#storage = AstroSession.#sharedStorage.get(this.#config.driver);
return this.#storage;
}
if (!this.#driverFactory) {
throw new AstroError({
...SessionStorageInitError,
message: SessionStorageInitError.message(
"Astro could not load the driver correctly. Does it exist?",
this.#config.driver
)
});
}
const driver = this.#driverFactory;
try {
this.#storage = createStorage({
driver: {
...driver(this.#config.options),
// Unused methods
hasItem() {
return false;
},
getKeys() {
return [];
}
}
});
AstroSession.#sharedStorage.set(this.#config.driver, this.#storage);
return this.#storage;
} catch (err) {
throw new AstroError(
{
...SessionStorageInitError,
message: SessionStorageInitError.message("Unknown error", this.#config.driver)
},
{ cause: err }
);
}
}
}
function validateAndDecodePathname(pathname) {
let decoded;
try {
decoded = decodeURI(pathname);
} catch (_e) {
throw new Error("Invalid URL encoding");
}
const hasDecoding = decoded !== pathname;
const decodedStillHasEncoding = /%[0-9a-fA-F]{2}/.test(decoded);
if (hasDecoding && decodedStillHasEncoding) {
throw new Error("Multi-level URL encoding is not allowed");
}
return decoded;
}
class RenderContext {
pipeline;
locals;
middleware;
actions;
serverIslands;
// It must be a DECODED pathname
pathname;
request;
routeData;
status;
clientAddress;
cookies;
params;
url;
props;
partial;
shouldInjectCspMetaTags;
session;
cache;
skipMiddleware;
constructor(pipeline, locals, middleware, actions, serverIslands, pathname, request, routeData, status, clientAddress, cookies = new AstroCookies(request), params = getParams(routeData, pathname), url = RenderContext.#createNormalizedUrl(request.url), props = {}, partial = void 0, shouldInjectCspMetaTags = pipeline.manifest.shouldInjectCspMetaTags, session = void 0, cache, skipMiddleware = false) {
this.pipeline = pipeline;
this.locals = locals;
this.middleware = middleware;
this.actions = actions;
this.serverIslands = serverIslands;
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.shouldInjectCspMetaTags = shouldInjectCspMetaTags;
this.session = session;
this.cache = cache;
this.skipMiddleware = skipMiddleware;
}
static #createNormalizedUrl(requestUrl) {
const url = new URL(requestUrl);
try {
url.pathname = validateAndDecodePathname(url.pathname);
} catch {
try {
url.pathname = decodeURI(url.pathname);
} catch {
}
}
url.pathname = collapseDuplicateSlashes(url.pathname);
return url;
}
/**
* A flag that tells the render content if the rewriting was triggered
*/
isRewriting = false;
/**
* A safety net in case of loops
*/
counter = 0;
result = void 0;
static async create({
locals = {},
pathname,
pipeline,
request,
routeData,
clientAddress,
status = 200,
props,
partial = void 0,
shouldInjectCspMetaTags,
skipMiddleware = false
}) {
const pipelineMiddleware = await pipeline.getMiddleware();
const pipelineActions = await pipeline.getActions();
const pipelineSessionDriver = await pipeline.getSessionDriver();
const serverIslands = await pipeline.getServerIslands();
setOriginPathname(
request,
pathname,
pipeline.manifest.trailingSlash,
pipeline.manifest.buildFormat
);
const cookies = new AstroCookies(request);
const session = pipeline.manifest.sessionConfig && pipelineSessionDriver ? new AstroSession({
cookies,
config: pipeline.manifest.sessionConfig,
runtimeMode: pipeline.runtimeMode,
driverFactory: pipelineSessionDriver,
mockStorage: null
}) : void 0;
let cache;
if (!pipeline.cacheConfig) {
cache = new DisabledAstroCache(pipeline.logger);
} else if (pipeline.runtimeMode === "development") {
cache = new NoopAstroCache();
} else {
const cacheProvider = await pipeline.getCacheProvider();
cache = new AstroCache(cacheProvider);
if (pipeline.cacheConfig?.routes) {
if (!pipeline.compiledCacheRoutes) {
pipeline.compiledCacheRoutes = compileCacheRoutes(
pipeline.cacheConfig.routes,
pipeline.manifest.base,
pipeline.manifest.trailingSlash
);
}
const matched = matchCacheRoute(pathname, pipeline.compiledCacheRoutes);
if (matched) {
cache.set(matched);
}
}
}
return new RenderContext(
pipeline,
locals,
sequence(...pipeline.internalMiddleware, pipelineMiddleware),
pipelineActions,
serverIslands,
pathname,
request,
routeData,
status,
clientAddress,
cookies,
void 0,
void 0,
props,
partial,
shouldInjectCspMetaTags ?? pipeline.manifest.shouldInjectCspMetaTags,
session,
cache,
skipMiddleware
);
}
/**
* 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
* - fallback
*/
async render(componentInstance, slots = {}) {
const { middleware, pipeline } = this;
const { logger, 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: manifest.serverLike,
base: manifest.base,
trailingSlash: manifest.trailingSlash
});
const actionApiContext = this.createActionAPIContext();
const apiContext = this.createAPIContext(props, actionApiContext);
this.counter++;
if (this.counter === 4) {
return new Response("Loop Detected", {
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/508
status: 508,
statusText: "Astro detected a loop where you tried to call the rewriting logic more than four times."
});
}
const lastNext = async (ctx, payload) => {
if (payload) {
const oldPathname = this.pathname;
pipeline.logger.debug("router", "Called rewriting to:", payload);
const {
routeData,
componentInstance: newComponent,
pathname,
newUrl
} = await pipeline.tryRewrite(payload, this.request);
if (this.pipeline.manifest.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,
// need to send the flag of the previous routeData
routeData.prerender,
this.pipeline.logger,
this.routeData.route
);
}
this.isRewriting = true;
this.url = RenderContext.#createNormalizedUrl(this.request.url);
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 && !this.skipMiddleware) {
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,
this.routeData.prerender,
logger
);
break;
}
case "redirect":
return renderRedirect(this);
case "page": {
this.result = await this.createResult(componentInstance, actionApiContext);
try {
response2 = await renderPage(
this.result,
componentInstance?.default,
props,
slots,
streaming,
this.routeData
);
} catch (e) {
this.result.cancelled = true;
throw e;
}
response2.headers.set(ROUTE_TYPE_HEADER, "page");
if (this.routeData.route === "/404" || this.routeData.route === "/500") {
response2.headers.set(REROUTE_DIRECTIVE_HEADER, "no");
}
if (this.isRewriting) {
response2.headers.set(REWRITE_DIRECTIVE_HEADER_KEY, REWRITE_DIRECTIVE_HEADER_VALUE);
}
break;
}
case "fallback": {
return new Response(null, { status: 500, headers: { [ROUTE_TYPE_HEADER]: "fallback" } });
}
}
const responseCookies = getCookiesFromResponse(response2);
if (responseCookies) {
this.cookies.merge(responseCookies);
}
return response2;
};
if (isRouteExternalRedirect(this.routeData)) {
return renderRedirect(this);
}
const response = this.skipMiddleware ? await lastNext(apiContext) : await callMiddleware(middleware, apiContext, lastNext);
if (response.headers.get(ROUTE_TYPE_HEADER)) {
response.headers.delete(ROUTE_TYPE_HEADER);
}
attachCookiesToResponse(response, this.cookies);
return response;
}
createAPIContext(props, context) {
const redirect = (path, status = 302) => new Response(null, { status, headers: { Location: path } });
const rewrite = async (reroutePayload) => {
return await this.#executeRewrite(reroutePayload);
};
Reflect.set(context, pipelineSymbol, this.pipeline);
return Object.assign(context, {
props,
redirect,
rewrite,
getActionResult: createGetActionResult(context.locals),
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.manifest.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,
// need to send the flag of the previous routeData
routeData.prerender,
this.pipeline.logger,
this.routeData.route
);
}
this.url = RenderContext.#createNormalizedUrl(this.request.url);
const newCookies = new AstroCookies(this.request);
if (this.cookies) {
newCookies.merge(this.cookies);
}
this.cookies = newCookies;
this.params = getParams(routeData, pathname);
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() {
const renderContext = this;
const { params, pipeline, url } = this;
return {
// Don't allow reassignment of cookies because it doesn't work
get cookies() {
return renderContext.cookies;
},
routePattern: this.routeData.route,
isPrerendered: this.routeData.prerender,
get clientAddress() {
return renderContext.getClientAddress();
},
get currentLocale() {
return renderContext.computeCurrentLocale();
},
generator: ASTRO_GENERATOR,
get locals() {
return renderContext.locals;
},
set locals(_) {
throw new AstroError(LocalsReassigned);
},
params,
get preferredLocale() {
return renderContext.computePreferredLocale();
},
get preferredLocaleList() {
return renderContext.computePreferredLocaleList();
},
request: this.request,
site: pipeline.site,
url,
get originPathname() {
return getOriginPathname(renderContext.request);
},
get session() {
if (this.isPrerendered) {
pipeline.logger.warn(
"session",
`context.session was used when rendering the route ${colors.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 ${colors.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 cache() {
return renderContext.cache;
},
get csp() {
if (!pipeline.manifest.csp) {
if (pipeline.runtimeMode === "production") {
pipeline.logger.warn(
"csp",
`context.csp was used when rendering the route ${colors.green(this.routePattern)}, but CSP was not configured. For more information, see https://docs.astro.build/en/reference/experimental-flags/csp/`
);
}
return void 0;
}
return {
insertDirective(payload) {
if (renderContext?.result?.directives) {
renderContext.result.directives = pushDirective(
renderContext.result.directives,
payload
);
} else {
renderContext?.result?.directives.push(payload);
}
},
insertScriptResource(resource) {
renderContext.result?.scriptResources.push(resource);
},
insertStyleResource(resource) {
renderContext.result?.styleResources.push(resource);
},
insertStyleHash(hash) {
renderContext.result?.styleHashes.push(hash);
},
insertScriptHash(hash) {
renderContext.result?.scriptHashes.push(hash);
}
};
},
get logger() {
if (!pipeline.manifest.experimentalLogger) {
pipeline.logger.warn(
null,
"The Astro.logger is available only when experimental.logger is defined."
);
return void 0;
}
return {
info(msg) {
pipeline.logger.info(null, msg);
},
warn(msg) {
pipeline.logger.warn(null, msg);
},
error(msg) {
pipeline.logger.error(null, msg);
}
};
}
};
}
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 = this.shouldInjectCspMetaTags;
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: actionResult?.error ? actionResult?.error.status : status,
statusText: actionResult?.error ? actionResult?.error.type : "OK",
get headers() {
return headers;
},
// Disallow `Astro.response.headers = new Headers`
set headers(_) {
throw new AstroError(AstroResponseHeadersReassigned);
}
};
const result = {
base: manifest.base,
userAssetsBase: manifest.userAssetsBase,
cancelled: false,
clientDirectives,
inlinedScripts,
componentMetadata,
compressHTML,
cookies,
/** This function returns the `Astro` faux-global */
createAstro: (props, slots) => this.createAstro(result, props, slots, ctx),
links,
params: this.params,
partial,
pathname,
renderers,
resolve,
response,
request: this.request,
scripts,
styles,
actionResult,
serverIslandNameMap: this.serverIslands.serverIslandNameMap ?? /* @__PURE__ */ new Map(),
key: manifest.key,
trailingSlash: manifest.trailingSlash,
_experimentalQueuedRendering: {
pool: pipeline.nodePool,
htmlStringCache: pipeline.htmlStringCache,
enabled: manifest.experimentalQueuedRendering?.enabled,
poolSize: manifest.experimentalQueuedRendering?.poolSize,
contentCache: manifest.experimentalQueuedRendering?.contentCache
},
_metadata: {
hasHydrationScript: false,
rendererSpecificHydrationScripts: /* @__PURE__ */ new Set(),
hasRenderedHead: false,
renderedScripts: /* @__PURE__ */ new Set(),
hasDirectives: /* @__PURE__ */ new Set(),
hasRenderedServerIslandRuntime: false,
headInTree: false,
extraHead: [],
extraStyleHashes,
extraScriptHashes,
propagators: /* @__PURE__ */ new Set(),
templateDepth: 0
},
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,
internalFetchHeaders: manifest.internalFetchHeaders
};
return result;
}
#astroPagePartial;
/**
* The Astro global is sourced in 3 different phases:
* - **Static**: `.generator` and `.glob` is printed by the compiler, instantiated once per process per astro file
* - **Page-level**: `.request`, `.cookies`, `.locals` etc. These remain the same for the duration of the request.
* - **Component-level**: `.props`, `.slots`, and `.self` are unique to each _use_ of each component.
*
* 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, props, slotValues, apiContext) {
let astroPagePartial;
if (this.isRewriting) {
astroPagePartial = this.#astroPagePartial = this.createAstroPagePartial(result, apiContext);
} else {
astroPagePartial = this.#astroPagePartial ??= this.createAstroPagePartial(result, apiContext);
}
const astroComponentPartial = { props, self: null };
const Astro = Object.assign(
Object.create(astroPagePartial),
astroComponentPartial
);
let _slots;
Object.defineProperty(Astro, "slots", {
get: () => {
if (!_slots) {
_slots = new Slots(
result,
slotValues,
this.pipeline.logger
);
}
return _slots;
}
});
return Astro;
}
createAstroPagePartial(result, apiContext) {
const renderContext = this;
const { cookies, locals, params, pipeline, url } = this;
const { response } = result;
const redirect = (path, status = 302) => {
if (this.request[responseSentSymbol$1]) {
throw new AstroError({
...ResponseSentError
});
}
return new Response(null, { status, headers: { Location: path } });
};
const rewrite = async (reroutePayload) => {
return await this.#executeRewrite(reroutePayload);
};
const callAction = createCallAction(apiContext);
return {
generator: ASTRO_GENERATOR,
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 ${colors.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 ${colors.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 cache() {
return renderContext.cache;
},
get clientAddress() {
return renderContext.getClientAddress();
},
get currentLocale() {
return renderContext.computeCurrentLocale();
},
params,
get preferredLocale() {
return renderContext.computePreferredLocale();
},
get preferredLocaleList() {
return renderContext.computePreferredLocaleList();
},
locals,
redirect,
rewrite,
request: this.request,
response,
site: pipeline.site,
getActionResult: createGetActionResult(locals),
get callAction() {
return callAction;
},
url,
get originPathname() {
return getOriginPathname(renderContext.request);
},
get csp() {
if (!pipeline.manifest.csp) {
if (pipeline.runtimeMode === "production") {
pipeline.logger.warn(
"csp",
`Astro.csp was used when rendering the route ${colors.green(this.routePattern)}, but CSP was not configured. For more information, see https://docs.astro.build/en/reference/experimental-flags/csp/`
);
}
return void 0;
}
return {
insertDirective(payload) {
if (renderContext?.result?.directives) {
renderContext.result.directives = pushDirective(
renderContext.result.directives,
payload
);
} else {
renderContext?.result?.directives.push(payload);
}
},
insertScriptResource(resource) {
renderContext.result?.scriptResources.push(resource);
},
insertStyleResource(resource) {
renderContext.result?.styleResources.push(resource);
},
insertStyleHash(hash) {
renderContext.result?.styleHashes.push(hash);
},
insertScriptHash(hash) {
renderContext.result?.scriptHashes.push(hash);
}
};
},
get logger() {
return {
info(msg) {
pipeline.logger.info(null, msg);
},
warn(msg) {
pipeline.logger.warn(null, msg);
},
error(msg) {
pipeline.logger.error(null, msg);
}
};
}
};
}
getClientAddress() {
const { pipeline, routeData, clientAddress } = this;
if (routeData.prerender) {
throw new AstroError({
...PrerenderClientAddressNotAvailable,
message: PrerenderClientAddressNotAvailable.message(routeData.component)
});
}
if (clientAddress) {
return clientAddress;
}
if (pipeline.adapterName) {
throw new AstroError({
...ClientAddressNotAvailable,
message: ClientAddressNotAvailable.message(pipeline.adapterName)
});
}
throw new AstroError(StaticClientAddressNotAvailable);
}
/**
* 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.
*/
#currentLocale;
computeCurrentLocale() {
const {
url,
pipeline: { i18n },
routeData
} = this;
if (!i18n) return;
const { defaultLocale, locales, strategy } = i18n;
const fallbackTo = strategy === "pathname-prefix-other-locales" || strategy === "domains-prefix-other-locales" ? defaultLocale : void 0;
if (this.#currentLocale) {
return this.#currentLocale;
}
let computedLocale;
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);
if (routeData.params.length > 0) {
const localeFromParams = computeCurrentLocaleFromParams(this.params, locales);
if (localeFromParams) {
computedLocale = localeFromParams;
}
}
}
this.#currentLocale = computedLocale ?? fallbackTo;
return this.#currentLocale;
}
#preferredLocale;
computePreferredLocale() {
const {
pipeline: { i18n },
request
} = this;
if (!i18n) return;
return this.#preferredLocale ??= computePreferredLocale(request, i18n.locales);
}
#preferredLocaleList;
computePreferredLocaleList() {
const {
pipeline: { i18n },
request
} = this;
if (!i18n) return;
return this.#preferredLocaleList ??= computePreferredLocaleList(request, i18n.locales);
}
}
function redirectTemplate({
status,
absoluteLocation,
relativeLocation,
from
}) {
const delay = status === 302 ? 2 : 0;
return `
${from} ` : ""}to ${relativeLocation}
`;
}
function ensure404Route(manifest) {
if (!manifest.routes.some((route) => route.route === "/404")) {
manifest.routes.push(DEFAULT_404_ROUTE);
}
return manifest;
}
class Router {
#routes;
#base;
#baseWithoutTrailingSlash;
#buildFormat;
#trailingSlash;
constructor(routes, options) {
this.#routes = [...routes].sort(routeComparator);
this.#base = normalizeBase(options.base);
this.#baseWithoutTrailingSlash = removeTrailingForwardSlash(this.#base);
this.#buildFormat = options.buildFormat;
this.#trailingSlash = options.trailingSlash;
}
/**
* Match an input pathname against the route list.
* If allowWithoutBase is true, a non-base-prefixed path is still considered.
*/
match(inputPathname, { allowWithoutBase = false } = {}) {
const normalized = getRedirectForPathname(inputPathname);
if (normalized.redirect) {
return { type: "redirect", location: normalized.redirect, status: 301 };
}
if (this.#base !== "/") {
const baseWithSlash = `${this.#baseWithoutTrailingSlash}/`;
if (this.#trailingSlash === "always" && (normalized.pathname === this.#baseWithoutTrailingSlash || normalized.pathname === this.#base)) {
return { type: "redirect", location: baseWithSlash, status: 301 };
}
if (this.#trailingSlash === "never" && normalized.pathname === baseWithSlash) {
return { type: "redirect", location: this.#baseWithoutTrailingSlash, status: 301 };
}
}
const baseResult = stripBase(
normalized.pathname,
this.#base,
this.#baseWithoutTrailingSlash,
this.#trailingSlash
);
if (!baseResult) {
if (!allowWithoutBase) {
return { type: "none", reason: "outside-base" };
}
}
let pathname = baseResult ?? normalized.pathname;
if (this.#buildFormat === "file") {
pathname = normalizeFileFormatPathname(pathname);
}
const route = this.#routes.find((candidate) => {
if (candidate.pattern.test(pathname)) return true;
return candidate.fallbackRoutes.some((fallbackRoute) => fallbackRoute.pattern.test(pathname));
});
if (!route) {
return { type: "none", reason: "no-match" };
}
const params = getParams(route, pathname);
return { type: "match", route, params, pathname };
}
}
function normalizeBase(base) {
if (!base) return "/";
if (base === "/") return base;
return prependForwardSlash(base);
}
function getRedirectForPathname(pathname) {
let value = prependForwardSlash(pathname);
if (value.startsWith("//")) {
const collapsed = `/${value.replace(/^\/+/, "")}`;
return { pathname: value, redirect: collapsed };
}
return { pathname: value };
}
function stripBase(pathname, base, baseWithoutTrailingSlash, trailingSlash) {
if (base === "/") return pathname;
const baseWithSlash = `${baseWithoutTrailingSlash}/`;
if (pathname === baseWithoutTrailingSlash || pathname === base) {
return trailingSlash === "always" ? null : "/";
}
if (pathname === baseWithSlash) {
return trailingSlash === "never" ? null : "/";
}
if (pathname.startsWith(baseWithSlash)) {
return pathname.slice(baseWithoutTrailingSlash.length);
}
return null;
}
function normalizeFileFormatPathname(pathname) {
if (pathname.endsWith("/index.html")) {
const trimmed = pathname.slice(0, -"/index.html".length);
return trimmed === "" ? "/" : trimmed;
}
if (pathname.endsWith(".html")) {
const trimmed = pathname.slice(0, -".html".length);
return trimmed === "" ? "/" : trimmed;
}
return pathname;
}
class BaseApp {
manifest;
manifestData;
pipeline;
#adapterLogger;
baseWithoutTrailingSlash;
#router;
get logger() {
return this.pipeline.logger;
}
get adapterLogger() {
if (!this.#adapterLogger) {
this.#adapterLogger = new AstroIntegrationLogger(
this.logger.options,
this.manifest.adapterName
);
}
return this.#adapterLogger;
}
constructor(manifest, streaming = true, ...args) {
this.manifest = manifest;
this.manifestData = { routes: manifest.routes.map((route) => route.routeData) };
this.baseWithoutTrailingSlash = removeTrailingForwardSlash(manifest.base);
this.pipeline = this.createPipeline(streaming, manifest, ...args);
ensure404Route(this.manifestData);
this.#router = this.createRouter(this.manifestData);
}
async createRenderContext(payload) {
return RenderContext.create(payload);
}
getAdapterLogger() {
return this.adapterLogger;
}
/**
* Resets the cached adapter logger so it picks up a new logger instance.
* Used by BuildApp when the logger is replaced via setOptions().
*/
resetAdapterLogger() {
this.#adapterLogger = void 0;
}
getAllowedDomains() {
return this.manifest.allowedDomains;
}
matchesAllowedDomains(forwardedHost, protocol) {
return BaseApp.validateForwardedHost(forwardedHost, this.manifest.allowedDomains, protocol);
}
static validateForwardedHost(forwardedHost, allowedDomains, protocol) {
if (!allowedDomains || allowedDomains.length === 0) {
return false;
}
try {
const testUrl = new URL(`${protocol || "https"}://${forwardedHost}`);
return allowedDomains.some((pattern) => {
return matchPattern(testUrl, pattern);
});
} catch {
return false;
}
}
set setManifestData(newManifestData) {
this.manifestData = newManifestData;
this.#router = this.createRouter(this.manifestData);
}
removeBase(pathname) {
pathname = collapseDuplicateLeadingSlashes(pathname);
if (pathname.startsWith(this.manifest.base)) {
return pathname.slice(this.baseWithoutTrailingSlash.length + 1);
}
return pathname;
}
/**
* It removes the base from the request URL, prepends it with a forward slash and attempts to decoded it.
*
* If the decoding fails, it logs the error and return the pathname as is.
* @param request
*/
getPathnameFromRequest(request) {
const url = new URL(request.url);
const pathname = prependForwardSlash(this.removeBase(url.pathname));
try {
return decodeURI(pathname);
} catch (e) {
this.getAdapterLogger().error(e.toString());
return pathname;
}
}
/**
* Given a `Request`, it returns the `RouteData` that matches its `pathname`. By default, prerendered
* routes aren't returned, even if they are matched.
*
* When `allowPrerenderedRoutes` is `true`, the function returns matched prerendered routes too.
* @param request
* @param allowPrerenderedRoutes
*/
match(request, allowPrerenderedRoutes = false) {
const url = new URL(request.url);
if (this.manifest.assets.has(url.pathname)) return void 0;
let pathname = this.computePathnameFromDomain(request);
if (!pathname) {
pathname = prependForwardSlash(this.removeBase(url.pathname));
}
const match = this.#router.match(decodeURI(pathname), { allowWithoutBase: true });
if (match.type !== "match") return void 0;
const routeData = match.route;
if (allowPrerenderedRoutes) {
return routeData;
} else if (routeData.prerender) {
return void 0;
}
return routeData;
}
createRouter(manifestData) {
return new Router(manifestData.routes, {
base: this.manifest.base,
trailingSlash: this.manifest.trailingSlash,
buildFormat: this.manifest.buildFormat
});
}
/**
* A matching route function to use in the development server.
* Contrary to the `.match` function, this function resolves props and params, returning the correct
* route based on the priority, segments. It also returns the correct, resolved pathname.
* @param pathname
*/
devMatch(pathname) {
return void 0;
}
computePathnameFromDomain(request) {
let pathname = void 0;
const url = new URL(request.url);
if (this.manifest.i18n && (this.manifest.i18n.strategy === "domains-prefix-always" || this.manifest.i18n.strategy === "domains-prefix-other-locales" || this.manifest.i18n.strategy === "domains-prefix-always-no-redirect")) {
let host = request.headers.get("X-Forwarded-Host");
let protocol = request.headers.get("X-Forwarded-Proto");
if (protocol) {
protocol = protocol + ":";
} else {
protocol = url.protocol;
}
if (!host) {
host = request.headers.get("Host");
}
if (host && protocol) {
host = host.split(":")[0];
try {
let locale;
const hostAsUrl = new URL(`${protocol}//${host}`);
for (const [domainKey, localeValue] of Object.entries(
this.manifest.i18n.domainLookupTable
)) {
const domainKeyAsUrl = new URL(domainKey);
if (hostAsUrl.host === domainKeyAsUrl.host && hostAsUrl.protocol === domainKeyAsUrl.protocol) {
locale = localeValue;
break;
}
}
if (locale) {
pathname = prependForwardSlash(
joinPaths(normalizeTheLocale(locale), this.removeBase(url.pathname))
);
if (this.manifest.trailingSlash === "always") {
pathname = appendForwardSlash(pathname);
} else if (this.manifest.trailingSlash === "never") {
pathname = removeTrailingForwardSlash(pathname);
} else if (url.pathname.endsWith("/")) {
pathname = appendForwardSlash(pathname);
}
}
} catch (e) {
this.logger.error(
"router",
`Astro tried to parse ${protocol}//${host} as an URL, but it threw a parsing error. Check the X-Forwarded-Host and X-Forwarded-Proto headers.`
);
this.logger.error("router", `Error: ${e}`);
}
}
}
return pathname;
}
redirectTrailingSlash(pathname) {
const { trailingSlash } = this.manifest;
if (pathname === "/" || isInternalPath(pathname)) {
return pathname;
}
const path = collapseDuplicateTrailingSlashes(pathname, trailingSlash !== "never");
if (path !== pathname) {
return path;
}
if (trailingSlash === "ignore") {
return pathname;
}
if (trailingSlash === "always" && !hasFileExtension(pathname)) {
return appendForwardSlash(pathname);
}
if (trailingSlash === "never") {
return removeTrailingForwardSlash(pathname);
}
return pathname;
}
async render(request, {
addCookieHeader = false,
clientAddress = Reflect.get(request, clientAddressSymbol),
locals,
prerenderedErrorPageFetch = fetch,
routeData,
waitUntil
} = {}) {
await this.pipeline.getLogger();
const timeStart = performance.now();
const url = new URL(request.url);
const redirect = this.redirectTrailingSlash(url.pathname);
if (redirect !== url.pathname) {
const status = request.method === "GET" ? 301 : 308;
const response2 = new Response(
redirectTemplate({
status,
relativeLocation: url.pathname,
absoluteLocation: redirect,
from: request.url
}),
{
status,
headers: {
location: redirect + url.search
}
}
);
this.#prepareResponse(response2, { addCookieHeader });
return response2;
}
if (routeData) {
this.logger.debug(
"router",
"The adapter " + this.manifest.adapterName + " provided a custom RouteData for ",
request.url
);
this.logger.debug("router", "RouteData");
this.logger.debug("router", routeData);
}
const resolvedRenderOptions = {
addCookieHeader,
clientAddress,
prerenderedErrorPageFetch,
locals,
routeData,
waitUntil
};
if (locals) {
if (typeof locals !== "object") {
const error = new AstroError(LocalsNotAnObject);
this.logger.error(null, error.stack);
return this.renderError(request, {
...resolvedRenderOptions,
// If locals are invalid, we don't want to include them when
// rendering the error page
locals: void 0,
status: 500,
error
});
}
}
if (!routeData) {
if (this.isDev()) {
const result = await this.devMatch(this.getPathnameFromRequest(request));
if (result) {
routeData = result.routeData;
}
} else {
routeData = this.match(request);
}
this.logger.debug("router", "Astro matched the following route for " + request.url);
this.logger.debug("router", "RouteData:\n" + routeData);
}
if (!routeData) {
routeData = this.manifestData.routes.find(
(route) => route.component === "404.astro" || route.component === DEFAULT_404_COMPONENT
);
}
if (!routeData) {
this.logger.debug("router", "Astro hasn't found routes that match " + request.url);
this.logger.debug("router", "Here's the available routes:\n", this.manifestData);
return this.renderError(request, {
...resolvedRenderOptions,
status: 404
});
}
let pathname = this.getPathnameFromRequest(request);
if (this.isDev() && !routeHasHtmlExtension(routeData)) {
pathname = pathname.replace(/\/index\.html$/, "/").replace(/\.html$/, "");
}
const defaultStatus = this.getDefaultStatusCode(routeData, pathname);
let response;
let session;
let cache;
try {
const componentInstance = await this.pipeline.getComponentByRoute(routeData);
const renderContext = await this.createRenderContext({
pipeline: this.pipeline,
locals,
pathname,
request,
routeData,
status: defaultStatus,
clientAddress
});
session = renderContext.session;
cache = renderContext.cache;
if (this.pipeline.cacheProvider) {
const cacheProvider = await this.pipeline.getCacheProvider();
if (cacheProvider?.onRequest) {
response = await cacheProvider.onRequest(
{
request,
url: new URL(request.url),
waitUntil: resolvedRenderOptions.waitUntil
},
async () => {
const res = await renderContext.render(componentInstance);
applyCacheHeaders(cache, res);
return res;
}
);
response.headers.delete("CDN-Cache-Control");
response.headers.delete("Cache-Tag");
} else {
response = await renderContext.render(componentInstance);
applyCacheHeaders(cache, response);
}
} else {
response = await renderContext.render(componentInstance);
}
const isRewrite = response.headers.has(REWRITE_DIRECTIVE_HEADER_KEY);
this.logThisRequest({
pathname,
method: request.method,
statusCode: response.status,
isRewrite,
timeStart
});
} catch (err) {
this.logger.error(null, err.stack || err.message || String(err));
return this.renderError(request, {
...resolvedRenderOptions,
status: 500,
error: err
});
} finally {
await session?.[PERSIST_SYMBOL]();
}
if (REROUTABLE_STATUS_CODES.includes(response.status) && // If the body isn't null, that means the user sets the 404 status
// but uses the current route to handle the 404
response.body === null && response.headers.get(REROUTE_DIRECTIVE_HEADER) !== "no") {
return this.renderError(request, {
...resolvedRenderOptions,
response,
status: response.status,
// We don't have an error to report here. Passing null means we pass nothing intentionally
// while undefined means there's no error
error: response.status === 500 ? null : void 0
});
}
this.#prepareResponse(response, { addCookieHeader });
return response;
}
#prepareResponse(response, { addCookieHeader }) {
for (const headerName of [
REROUTE_DIRECTIVE_HEADER,
REWRITE_DIRECTIVE_HEADER_KEY,
NOOP_MIDDLEWARE_HEADER,
ROUTE_TYPE_HEADER
]) {
if (response.headers.has(headerName)) {
response.headers.delete(headerName);
}
}
if (addCookieHeader) {
for (const setCookieHeaderValue of getSetCookiesFromResponse(response)) {
response.headers.append("set-cookie", setCookieHeaderValue);
}
}
this.logger.flush();
Reflect.set(response, responseSentSymbol$1, true);
}
setCookieHeaders(response) {
return getSetCookiesFromResponse(response);
}
/**
* Reads all the cookies written by `Astro.cookie.set()` onto the passed response.
* For example,
* ```ts
* for (const cookie_ of App.getSetCookieFromResponse(response)) {
* const cookie: string = cookie_
* }
* ```
* @param response The response to read cookies from.
* @returns An iterator that yields key-value pairs as equal-sign-separated strings.
*/
static getSetCookieFromResponse = getSetCookiesFromResponse;
/**
* If it is a known error code, try sending the according page (e.g. 404.astro / 500.astro).
* This also handles pre-rendered /404 or /500 routes
*/
async renderError(request, {
status,
response: originalResponse,
skipMiddleware = false,
error,
...resolvedRenderOptions
}) {
const errorRoutePath = `/${status}${this.manifest.trailingSlash === "always" ? "/" : ""}`;
const errorRouteData = matchRoute(errorRoutePath, this.manifestData);
const url = new URL(request.url);
if (errorRouteData) {
if (errorRouteData.prerender) {
const maybeDotHtml = errorRouteData.route.endsWith(`/${status}`) ? ".html" : "";
const statusURL = new URL(`${this.baseWithoutTrailingSlash}/${status}${maybeDotHtml}`, url);
if (statusURL.toString() !== request.url && resolvedRenderOptions.prerenderedErrorPageFetch) {
const response2 = await resolvedRenderOptions.prerenderedErrorPageFetch(
statusURL.toString()
);
const override = { status, removeContentEncodingHeaders: true };
const newResponse = this.mergeResponses(response2, originalResponse, override);
this.#prepareResponse(newResponse, resolvedRenderOptions);
return newResponse;
}
}
const mod = await this.pipeline.getComponentByRoute(errorRouteData);
let session;
try {
const renderContext = await this.createRenderContext({
locals: resolvedRenderOptions.locals,
pipeline: this.pipeline,
skipMiddleware,
pathname: this.getPathnameFromRequest(request),
request,
routeData: errorRouteData,
status,
props: { error },
clientAddress: resolvedRenderOptions.clientAddress
});
session = renderContext.session;
const response2 = await renderContext.render(mod);
const newResponse = this.mergeResponses(response2, originalResponse);
this.#prepareResponse(newResponse, resolvedRenderOptions);
return newResponse;
} catch {
if (skipMiddleware === false) {
return this.renderError(request, {
...resolvedRenderOptions,
status,
response: originalResponse,
skipMiddleware: true
});
}
} finally {
await session?.[PERSIST_SYMBOL]();
}
}
const response = this.mergeResponses(new Response(null, { status }), originalResponse);
this.#prepareResponse(response, resolvedRenderOptions);
return response;
}
mergeResponses(newResponse, originalResponse, override) {
let newResponseHeaders = newResponse.headers;
if (override?.removeContentEncodingHeaders) {
newResponseHeaders = new Headers(newResponseHeaders);
newResponseHeaders.delete("Content-Encoding");
newResponseHeaders.delete("Content-Length");
}
if (!originalResponse) {
if (override !== void 0) {
return new Response(newResponse.body, {
status: override.status,
statusText: newResponse.statusText,
headers: newResponseHeaders
});
}
return newResponse;
}
const status = override?.status ? override.status : originalResponse.status === 200 ? newResponse.status : originalResponse.status;
try {
originalResponse.headers.delete("Content-type");
originalResponse.headers.delete("Content-Length");
originalResponse.headers.delete("Transfer-Encoding");
} catch {
}
const newHeaders = new Headers();
const seen = /* @__PURE__ */ new Set();
for (const [name, value] of originalResponse.headers) {
newHeaders.append(name, value);
seen.add(name.toLowerCase());
}
for (const [name, value] of newResponseHeaders) {
if (!seen.has(name.toLowerCase())) {
newHeaders.append(name, value);
}
}
const mergedResponse = new Response(newResponse.body, {
status,
statusText: status === 200 ? newResponse.statusText : originalResponse.statusText,
// If you're looking at here for possible bugs, it means that it's not a bug.
// With the middleware, users can meddle with headers, and we should pass to the 404/500.
// If users see something weird, it's because they are setting some headers they should not.
//
// Although, we don't want it to replace the content-type, because the error page must return `text/html`
headers: newHeaders
});
const originalCookies = getCookiesFromResponse(originalResponse);
const newCookies = getCookiesFromResponse(newResponse);
if (originalCookies) {
if (newCookies) {
for (const cookieValue of AstroCookies.consume(newCookies)) {
originalResponse.headers.append("set-cookie", cookieValue);
}
}
attachCookiesToResponse(mergedResponse, originalCookies);
} else if (newCookies) {
attachCookiesToResponse(mergedResponse, newCookies);
}
return mergedResponse;
}
getDefaultStatusCode(routeData, pathname) {
if (!routeData.pattern.test(pathname)) {
for (const fallbackRoute of routeData.fallbackRoutes) {
if (fallbackRoute.pattern.test(pathname)) {
return 302;
}
}
}
const route = removeTrailingForwardSlash(routeData.route);
if (route.endsWith("/404")) return 404;
if (route.endsWith("/500")) return 500;
return 200;
}
getManifest() {
return this.pipeline.manifest;
}
logThisRequest({
pathname,
method,
statusCode,
isRewrite,
timeStart
}) {
const timeEnd = performance.now();
this.logRequest({
pathname,
method,
statusCode,
isRewrite,
reqTime: timeEnd - timeStart
});
}
}
function getAssetsPrefix(fileExtension, assetsPrefix) {
let prefix = "";
if (!assetsPrefix) {
prefix = "";
} else if (typeof assetsPrefix === "string") {
prefix = assetsPrefix;
} else {
const dotLessFileExtension = fileExtension.slice(1);
prefix = assetsPrefix[dotLessFileExtension] || assetsPrefix.fallback;
}
return prefix;
}
const URL_PARSE_BASE = "https://astro.build";
function splitAssetPath(path) {
const parsed = new URL(path, URL_PARSE_BASE);
const isAbsolute = URL.canParse(path);
const pathname = !isAbsolute && !path.startsWith("/") ? parsed.pathname.slice(1) : parsed.pathname;
return {
pathname,
suffix: `${parsed.search}${parsed.hash}`
};
}
function createAssetLink(href, base, assetsPrefix, queryParams) {
const { pathname, suffix } = splitAssetPath(href);
let url = "";
if (assetsPrefix) {
const pf = getAssetsPrefix(fileExtension(pathname), assetsPrefix);
url = joinPaths(pf, slash(pathname)) + suffix;
} else if (base) {
url = prependForwardSlash(joinPaths(base, slash(pathname))) + suffix;
} else {
url = href;
}
return url;
}
function createStylesheetElement(stylesheet, base, assetsPrefix, queryParams) {
if (stylesheet.type === "inline") {
return {
props: {},
children: stylesheet.content
};
} else {
return {
props: {
rel: "stylesheet",
href: createAssetLink(stylesheet.src, base, assetsPrefix)
},
children: ""
};
}
}
function createStylesheetElementSet(stylesheets, base, assetsPrefix, queryParams) {
return new Set(
stylesheets.map((s) => createStylesheetElement(s, base, assetsPrefix))
);
}
const slotName = (str) => str.trim().replace(/[-_]([a-z])/g, (_, w) => w.toUpperCase());
async function check(Component, props, { default: children = null, ...slotted } = {}) {
if (typeof Component !== "function") return false;
const slots = {};
for (const [key, value] of Object.entries(slotted)) {
const name = slotName(key);
slots[name] = value;
}
try {
const result = await Component({ ...props, ...slots, children });
return result[AstroJSX];
} catch (e) {
throwEnhancedErrorIfMdxComponent(e, Component);
}
return false;
}
async function renderToStaticMarkup(Component, props = {}, { default: children = null, ...slotted } = {}) {
const slots = {};
for (const [key, value] of Object.entries(slotted)) {
const name = slotName(key);
slots[name] = value;
}
const { result } = this;
try {
const html = await renderJSX(result, createVNode(Component, { ...props, ...slots, children }));
return { html };
} catch (e) {
throwEnhancedErrorIfMdxComponent(e, Component);
throw e;
}
}
function throwEnhancedErrorIfMdxComponent(error, Component) {
if (Component[/* @__PURE__ */ Symbol.for("mdx-component")]) {
if (AstroUserError.is(error)) return;
error.title = error.name;
error.hint = `This issue often occurs when your MDX component encounters runtime errors.`;
throw error;
}
}
const renderer = {
name: "astro:jsx",
check,
renderToStaticMarkup
};
var server_default = renderer;
const renderers = [Object.assign({"name":"astro:jsx","serverEntrypoint":"file:///C:/Users/Harun/OneDrive/Desktop/my%20pc%20desktop/node_modules/@astrojs/mdx/dist/server.js"}, { ssr: server_default }),];
const serializedData = [{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"type":"page","isIndex":false,"route":"/404","pattern":"^\\/404\\/?$","segments":[[{"content":"404","dynamic":false,"spread":false}]],"params":[],"component":"node_modules/@astrojs/starlight/routes/static/404.astro","pathname":"/404","prerender":true,"fallbackRoutes":[],"distURL":[],"origin":"external","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"route":"/about","isIndex":false,"type":"page","pattern":"^\\/about\\/?$","segments":[[{"content":"about","dynamic":false,"spread":false}]],"params":[],"component":"src/pages/about.astro","pathname":"/about","prerender":true,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"route":"/articles/[slug]","isIndex":false,"type":"page","pattern":"^\\/articles\\/([^/]+?)\\/?$","segments":[[{"content":"articles","dynamic":false,"spread":false}],[{"content":"slug","dynamic":true,"spread":false}]],"params":["slug"],"component":"src/pages/articles/[slug].astro","prerender":true,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"route":"/articles","isIndex":true,"type":"page","pattern":"^\\/articles\\/?$","segments":[[{"content":"articles","dynamic":false,"spread":false}]],"params":[],"component":"src/pages/articles/index.astro","pathname":"/articles","prerender":true,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"route":"/contact","isIndex":false,"type":"page","pattern":"^\\/contact\\/?$","segments":[[{"content":"contact","dynamic":false,"spread":false}]],"params":[],"component":"src/pages/contact.astro","pathname":"/contact","prerender":true,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"route":"/","isIndex":true,"type":"page","pattern":"^\\/$","segments":[],"params":[],"component":"src/pages/index.astro","pathname":"/","prerender":true,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[],"styles":[],"routeData":{"type":"page","isIndex":false,"route":"/[...slug]","pattern":"^(?:\\/(.*?))?\\/?$","segments":[[{"content":"...slug","dynamic":true,"spread":true}]],"params":["...slug"],"component":"node_modules/@astrojs/starlight/routes/static/index.astro","prerender":true,"fallbackRoutes":[],"distURL":[],"origin":"external","_meta":{"trailingSlash":"ignore"}}}];
serializedData.map(deserializeRouteInfo);
const _page0 = () => import('./404_BN0AmpT8.mjs');
const _page1 = () => import('./about_mO09-rr8.mjs');
const _page2 = () => import('./_slug__FNaN52r3.mjs');
const _page3 = () => import('./index_D9IeIxh-.mjs');
const _page4 = () => import('./contact_CBxMxonn.mjs');
const _page5 = () => import('./index_Nguhw-YR.mjs');
const _page6 = () => import('./index_DkAZzI2h.mjs');
const pageMap = new Map([
["node_modules/@astrojs/starlight/routes/static/404.astro", _page0],
["src/pages/about.astro", _page1],
["src/pages/articles/[slug].astro", _page2],
["src/pages/articles/index.astro", _page3],
["src/pages/contact.astro", _page4],
["src/pages/index.astro", _page5],
["node_modules/@astrojs/starlight/routes/static/index.astro", _page6]
]);
const _manifest = deserializeManifest(({"rootDir":"file:///C:/Users/Harun/OneDrive/Desktop/my%20pc%20desktop/","cacheDir":"file:///C:/Users/Harun/OneDrive/Desktop/my%20pc%20desktop/node_modules/.astro/","outDir":"file:///C:/Users/Harun/OneDrive/Desktop/my%20pc%20desktop/dist/","srcDir":"file:///C:/Users/Harun/OneDrive/Desktop/my%20pc%20desktop/src/","publicDir":"file:///C:/Users/Harun/OneDrive/Desktop/my%20pc%20desktop/public/","buildClientDir":"file:///C:/Users/Harun/OneDrive/Desktop/my%20pc%20desktop/dist/client/","buildServerDir":"file:///C:/Users/Harun/OneDrive/Desktop/my%20pc%20desktop/dist/server/","adapterName":"","assetsDir":"_astro","routes":[{"file":"","links":[],"scripts":[{"type":"external","value":"_astro/page.BIhdncjw.js"}],"styles":[{"type":"external","src":"_astro/common.DzFF2Dhy.css"},{"type":"external","src":"_astro/Code.BcHZMqfA.css"}],"routeData":{"type":"page","isIndex":false,"route":"/404","pattern":"^\\/404\\/?$","segments":[[{"content":"404","dynamic":false,"spread":false}]],"params":[],"component":"node_modules/@astrojs/starlight/routes/static/404.astro","pathname":"/404","prerender":true,"fallbackRoutes":[],"distURL":[],"origin":"external","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[{"type":"external","value":"_astro/page.BIhdncjw.js"}],"styles":[{"type":"inline","content":"*{box-sizing:border-box}body{margin:0;font-family:system-ui,Arial,sans-serif;line-height:1.6;color:#111827;background:#fff}a{color:#0369a1;text-decoration:none}img{max-width:100%;height:auto}.site-header{display:flex;justify-content:space-between;align-items:center;padding:16px 24px;border-bottom:1px solid #e5e7eb}.logo{font-weight:700;font-size:22px}nav{display:flex;gap:16px}main{max-width:1100px;margin:0 auto;padding:32px 24px}.site-footer{padding:24px;border-top:1px solid #e5e7eb;text-align:center}\n"}],"routeData":{"route":"/about","isIndex":false,"type":"page","pattern":"^\\/about\\/?$","segments":[[{"content":"about","dynamic":false,"spread":false}]],"params":[],"component":"src/pages/about.astro","pathname":"/about","prerender":true,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[{"type":"external","value":"_astro/page.BIhdncjw.js"}],"styles":[{"type":"inline","content":"*{box-sizing:border-box}body{margin:0;font-family:system-ui,Arial,sans-serif;line-height:1.6;color:#111827;background:#fff}a{color:#0369a1;text-decoration:none}img{max-width:100%;height:auto}.site-header{display:flex;justify-content:space-between;align-items:center;padding:16px 24px;border-bottom:1px solid #e5e7eb}.logo{font-weight:700;font-size:22px}nav{display:flex;gap:16px}main{max-width:1100px;margin:0 auto;padding:32px 24px}.site-footer{padding:24px;border-top:1px solid #e5e7eb;text-align:center}\n"}],"routeData":{"route":"/articles/[slug]","isIndex":false,"type":"page","pattern":"^\\/articles\\/([^/]+?)\\/?$","segments":[[{"content":"articles","dynamic":false,"spread":false}],[{"content":"slug","dynamic":true,"spread":false}]],"params":["slug"],"component":"src/pages/articles/[slug].astro","prerender":true,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[{"type":"external","value":"_astro/page.BIhdncjw.js"}],"styles":[{"type":"inline","content":"*{box-sizing:border-box}body{margin:0;font-family:system-ui,Arial,sans-serif;line-height:1.6;color:#111827;background:#fff}a{color:#0369a1;text-decoration:none}img{max-width:100%;height:auto}.site-header{display:flex;justify-content:space-between;align-items:center;padding:16px 24px;border-bottom:1px solid #e5e7eb}.logo{font-weight:700;font-size:22px}nav{display:flex;gap:16px}main{max-width:1100px;margin:0 auto;padding:32px 24px}.site-footer{padding:24px;border-top:1px solid #e5e7eb;text-align:center}\n.article-card:where(.astro-di2nlc57){padding:20px;border:1px solid #e5e7eb;border-radius:12px;margin-bottom:16px}.article-card:where(.astro-di2nlc57) h2:where(.astro-di2nlc57){margin-top:0}\n"}],"routeData":{"route":"/articles","isIndex":true,"type":"page","pattern":"^\\/articles\\/?$","segments":[[{"content":"articles","dynamic":false,"spread":false}]],"params":[],"component":"src/pages/articles/index.astro","pathname":"/articles","prerender":true,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[{"type":"external","value":"_astro/page.BIhdncjw.js"}],"styles":[{"type":"inline","content":"*{box-sizing:border-box}body{margin:0;font-family:system-ui,Arial,sans-serif;line-height:1.6;color:#111827;background:#fff}a{color:#0369a1;text-decoration:none}img{max-width:100%;height:auto}.site-header{display:flex;justify-content:space-between;align-items:center;padding:16px 24px;border-bottom:1px solid #e5e7eb}.logo{font-weight:700;font-size:22px}nav{display:flex;gap:16px}main{max-width:1100px;margin:0 auto;padding:32px 24px}.site-footer{padding:24px;border-top:1px solid #e5e7eb;text-align:center}\n"}],"routeData":{"route":"/contact","isIndex":false,"type":"page","pattern":"^\\/contact\\/?$","segments":[[{"content":"contact","dynamic":false,"spread":false}]],"params":[],"component":"src/pages/contact.astro","pathname":"/contact","prerender":true,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[{"type":"external","value":"_astro/page.BIhdncjw.js"}],"styles":[{"type":"inline","content":"*{box-sizing:border-box}body{margin:0;font-family:system-ui,Arial,sans-serif;line-height:1.6;color:#111827;background:#fff}a{color:#0369a1;text-decoration:none}img{max-width:100%;height:auto}.site-header{display:flex;justify-content:space-between;align-items:center;padding:16px 24px;border-bottom:1px solid #e5e7eb}.logo{font-weight:700;font-size:22px}nav{display:flex;gap:16px}main{max-width:1100px;margin:0 auto;padding:32px 24px}.site-footer{padding:24px;border-top:1px solid #e5e7eb;text-align:center}\n"}],"routeData":{"route":"/","isIndex":true,"type":"page","pattern":"^\\/$","segments":[],"params":[],"component":"src/pages/index.astro","pathname":"/","prerender":true,"fallbackRoutes":[],"distURL":[],"origin":"project","_meta":{"trailingSlash":"ignore"}}},{"file":"","links":[],"scripts":[{"type":"external","value":"_astro/page.BIhdncjw.js"}],"styles":[{"type":"external","src":"_astro/common.DzFF2Dhy.css"},{"type":"external","src":"_astro/Code.BcHZMqfA.css"}],"routeData":{"type":"page","isIndex":false,"route":"/[...slug]","pattern":"^(?:\\/(.*?))?\\/?$","segments":[[{"content":"...slug","dynamic":true,"spread":true}]],"params":["...slug"],"component":"node_modules/@astrojs/starlight/routes/static/index.astro","prerender":true,"fallbackRoutes":[],"distURL":[],"origin":"external","_meta":{"trailingSlash":"ignore"}}}],"serverLike":false,"middlewareMode":"classic","base":"/","trailingSlash":"ignore","compressHTML":true,"experimentalQueuedRendering":{"enabled":false,"poolSize":0,"contentCache":false},"componentMetadata":[["C:/Users/Harun/OneDrive/Desktop/my pc desktop/src/pages/about.astro",{"propagation":"none","containsHead":true}],["C:/Users/Harun/OneDrive/Desktop/my pc desktop/src/pages/articles/[slug].astro",{"propagation":"none","containsHead":true}],["C:/Users/Harun/OneDrive/Desktop/my pc desktop/src/pages/articles/index.astro",{"propagation":"none","containsHead":true}],["C:/Users/Harun/OneDrive/Desktop/my pc desktop/src/pages/contact.astro",{"propagation":"none","containsHead":true}],["C:/Users/Harun/OneDrive/Desktop/my pc desktop/src/pages/index.astro",{"propagation":"none","containsHead":true}],["C:/Users/Harun/OneDrive/Desktop/my pc desktop/node_modules/@astrojs/starlight/routes/static/404.astro",{"propagation":"in-tree","containsHead":true}],["C:/Users/Harun/OneDrive/Desktop/my pc desktop/node_modules/@astrojs/starlight/routes/static/index.astro",{"propagation":"in-tree","containsHead":true}],["\u0000astro:content",{"propagation":"in-tree","containsHead":false}],["C:/Users/Harun/OneDrive/Desktop/my pc desktop/node_modules/@astrojs/starlight/routes/common.astro",{"propagation":"in-tree","containsHead":false}],["\u0000virtual:astro:page:node_modules/@astrojs/starlight/routes/static/404@_@astro",{"propagation":"in-tree","containsHead":false}],["\u0000virtual:astro:pages",{"propagation":"in-tree","containsHead":false}],["\u0000virtual:astro:manifest",{"propagation":"in-tree","containsHead":false}],["C:/Users/Harun/OneDrive/Desktop/my pc desktop/node_modules/astro/dist/entrypoints/prerender.js",{"propagation":"in-tree","containsHead":false}],["\u0000virtual:astro:page:node_modules/@astrojs/starlight/routes/static/index@_@astro",{"propagation":"in-tree","containsHead":false}],["C:/Users/Harun/OneDrive/Desktop/my pc desktop/node_modules/@astrojs/starlight/utils/routing/data.ts",{"propagation":"in-tree","containsHead":false}],["C:/Users/Harun/OneDrive/Desktop/my pc desktop/node_modules/@astrojs/starlight/utils/routing/index.ts",{"propagation":"in-tree","containsHead":false}],["C:/Users/Harun/OneDrive/Desktop/my pc desktop/node_modules/@astrojs/starlight/utils/navigation.ts",{"propagation":"in-tree","containsHead":false}],["C:/Users/Harun/OneDrive/Desktop/my pc desktop/node_modules/@astrojs/starlight/components/SidebarPersister.astro",{"propagation":"in-tree","containsHead":false}],["C:/Users/Harun/OneDrive/Desktop/my pc desktop/node_modules/@astrojs/starlight/components/Sidebar.astro",{"propagation":"in-tree","containsHead":false}],["\u0000virtual:starlight/components/Sidebar",{"propagation":"in-tree","containsHead":false}],["C:/Users/Harun/OneDrive/Desktop/my pc desktop/node_modules/@astrojs/starlight/components/SidebarSublist.astro",{"propagation":"in-tree","containsHead":false}],["C:/Users/Harun/OneDrive/Desktop/my pc desktop/node_modules/@astrojs/starlight/utils/translations.ts",{"propagation":"in-tree","containsHead":false}],["C:/Users/Harun/OneDrive/Desktop/my pc desktop/node_modules/@astrojs/starlight/internal.ts",{"propagation":"in-tree","containsHead":false}],["C:/Users/Harun/OneDrive/Desktop/my pc desktop/node_modules/@astrojs/starlight/locals.ts",{"propagation":"in-tree","containsHead":false}],["\u0000virtual:astro:middleware",{"propagation":"in-tree","containsHead":false}]],"renderers":[],"clientDirectives":[["idle","(()=>{var l=(n,t)=>{let i=async()=>{await(await n())()},e=typeof t.value==\"object\"?t.value:void 0,s={timeout:e==null?void 0:e.timeout};\"requestIdleCallback\"in window?window.requestIdleCallback(i,s):setTimeout(i,s.timeout||200)};(self.Astro||(self.Astro={})).idle=l;window.dispatchEvent(new Event(\"astro:idle\"));})();"],["load","(()=>{var e=async t=>{await(await t())()};(self.Astro||(self.Astro={})).load=e;window.dispatchEvent(new Event(\"astro:load\"));})();"],["media","(()=>{var n=(a,t)=>{let i=async()=>{await(await a())()};if(t.value){let e=matchMedia(t.value);e.matches?i():e.addEventListener(\"change\",i,{once:!0})}};(self.Astro||(self.Astro={})).media=n;window.dispatchEvent(new Event(\"astro:media\"));})();"],["only","(()=>{var e=async t=>{await(await t())()};(self.Astro||(self.Astro={})).only=e;window.dispatchEvent(new Event(\"astro:only\"));})();"],["visible","(()=>{var a=(s,i,o)=>{let r=async()=>{await(await s())()},t=typeof i.value==\"object\"?i.value:void 0,c={rootMargin:t==null?void 0:t.rootMargin},n=new IntersectionObserver(e=>{for(let l of e)if(l.isIntersecting){n.disconnect(),r();break}},c);for(let e of o.children)n.observe(e)};(self.Astro||(self.Astro={})).visible=a;window.dispatchEvent(new Event(\"astro:visible\"));})();"]],"entryModules":{"\u0000virtual:astro:actions/noop-entrypoint":"chunks/noop-entrypoint_BOlrdqWF.mjs","\u0000virtual:astro:middleware":"chunks/_virtual_astro_middleware_BNm4SpGT.mjs","\u0000virtual:astro:session-driver":"chunks/_virtual_astro_session-driver_DYx9Bb3p.mjs","\u0000virtual:astro:server-island-manifest":"chunks/_virtual_astro_server-island-manifest_CQQ1F5PF.mjs","\u0000virtual:astro:page:node_modules/@astrojs/starlight/routes/static/404@_@astro":"chunks/404_BN0AmpT8.mjs","\u0000virtual:astro:page:src/pages/about@_@astro":"chunks/about_mO09-rr8.mjs","\u0000virtual:astro:page:src/pages/articles/[slug]@_@astro":"chunks/_slug__FNaN52r3.mjs","\u0000virtual:astro:page:src/pages/articles/index@_@astro":"chunks/index_D9IeIxh-.mjs","\u0000virtual:astro:page:src/pages/contact@_@astro":"chunks/contact_CBxMxonn.mjs","\u0000virtual:astro:page:src/pages/index@_@astro":"chunks/index_Nguhw-YR.mjs","\u0000virtual:astro:page:node_modules/@astrojs/starlight/routes/static/index@_@astro":"chunks/index_DkAZzI2h.mjs","C:\\Users\\Harun\\OneDrive\\Desktop\\my pc desktop\\.astro\\content-assets.mjs":"chunks/content-assets_BAMCPLHh.mjs","\u0000virtual:astro:get-image":"chunks/_virtual_astro_get-image_B78SXbXJ.mjs","C:\\Users\\Harun\\OneDrive\\Desktop\\my pc desktop\\.astro\\content-modules.mjs":"chunks/content-modules_DWClcio9.mjs","\u0000astro:data-layer-content":"chunks/_astro_data-layer-content_Cmfc1iOE.mjs","\u0000virtual:astro-expressive-code/config":"chunks/config_JSx-82B-.mjs","C:/Users/Harun/OneDrive/Desktop/my pc desktop/node_modules/astro-expressive-code/dist/index.js":"chunks/index_BD-MIWs7.mjs","\u0000virtual:astro-expressive-code/preprocess-config":"chunks/preprocess-config_m1vAPKKt.mjs","C:/Users/Harun/OneDrive/Desktop/my pc desktop/node_modules/astro/dist/assets/services/sharp.js":"chunks/sharp_CRb0jIiB.mjs","C:/Users/Harun/OneDrive/Desktop/my pc desktop/src/content/docs/index.mdx?astroPropagatedAssets":"chunks/index_BnaSx3Et.mjs","\u0000virtual:astro-expressive-code/ec-config":"chunks/ec-config_CzTTOeiV.mjs","C:/Users/Harun/OneDrive/Desktop/my pc desktop/src/content/docs/index.mdx":"chunks/index_Bqt0Uj9X.mjs","astro/entrypoints/prerender":"prerender-entry.CEIvaNt8.mjs","C:/Users/Harun/OneDrive/Desktop/my pc desktop/node_modules/@astrojs/starlight/components/LanguageSelect.astro?astro&type=script&index=0&lang.ts":"_astro/LanguageSelect.astro_astro_type_script_index_0_lang.Ce-i7NLC.js","C:/Users/Harun/OneDrive/Desktop/my pc desktop/node_modules/@astrojs/starlight/components/MobileMenuToggle.astro?astro&type=script&index=0&lang.ts":"_astro/MobileMenuToggle.astro_astro_type_script_index_0_lang.CsfLbggW.js","C:/Users/Harun/OneDrive/Desktop/my pc desktop/node_modules/@astrojs/starlight/components/MobileTableOfContents.astro?astro&type=script&index=0&lang.ts":"_astro/MobileTableOfContents.astro_astro_type_script_index_0_lang.hwBsy0Mo.js","C:/Users/Harun/OneDrive/Desktop/my pc desktop/node_modules/@astrojs/starlight/components/Page.astro?astro&type=script&index=0&lang.ts":"_astro/Page.astro_astro_type_script_index_0_lang.BHQeG8Vj.js","C:/Users/Harun/OneDrive/Desktop/my pc desktop/node_modules/@astrojs/starlight/components/ThemeSelect.astro?astro&type=script&index=0&lang.ts":"_astro/ThemeSelect.astro_astro_type_script_index_0_lang.Znk7Hhgg.js","C:/Users/Harun/OneDrive/Desktop/my pc desktop/node_modules/@astrojs/starlight/user-components/Tabs.astro?astro&type=script&index=0&lang.ts":"_astro/Tabs.astro_astro_type_script_index_0_lang._fLr8MwR.js","C:/Users/Harun/OneDrive/Desktop/my pc desktop/node_modules/@pagefind/default-ui/npm_dist/mjs/ui-core.mjs":"_astro/ui-core.D2oRCWSx.js","C:/Users/Harun/OneDrive/Desktop/my pc desktop/node_modules/@astrojs/starlight/components/Search.astro?astro&type=script&index=0&lang.ts":"_astro/Search.astro_astro_type_script_index_0_lang.Rw77DzG6.js","astro:scripts/page.js":"_astro/page.BIhdncjw.js","C:/Users/Harun/OneDrive/Desktop/my pc desktop/node_modules/@astrojs/starlight/components/TableOfContents.astro?astro&type=script&index=0&lang.ts":"_astro/TableOfContents.astro_astro_type_script_index_0_lang.FuRcXuRY.js","astro:scripts/before-hydration.js":""},"inlinedScripts":[["C:/Users/Harun/OneDrive/Desktop/my pc desktop/node_modules/@astrojs/starlight/components/LanguageSelect.astro?astro&type=script&index=0&lang.ts","class s extends HTMLElement{constructor(){super();const e=this.querySelector(\"select\");e&&(e.addEventListener(\"change\",t=>{t.currentTarget instanceof HTMLSelectElement&&(window.location.pathname=t.currentTarget.value)}),window.addEventListener(\"pageshow\",t=>{if(!t.persisted)return;const n=e.querySelector(\"option[selected]\")?.index;n!==e.selectedIndex&&(e.selectedIndex=n??0)}))}}customElements.define(\"starlight-lang-select\",s);"],["C:/Users/Harun/OneDrive/Desktop/my pc desktop/node_modules/@astrojs/starlight/components/MobileMenuToggle.astro?astro&type=script&index=0&lang.ts","class s extends HTMLElement{constructor(){super(),this.btn=this.querySelector(\"button\"),this.btn.addEventListener(\"click\",()=>this.toggleExpanded());const t=this.closest(\"nav\");t&&t.addEventListener(\"keyup\",e=>this.closeOnEscape(e))}setExpanded(t){this.setAttribute(\"aria-expanded\",String(t)),document.body.toggleAttribute(\"data-mobile-menu-expanded\",t)}toggleExpanded(){this.setExpanded(this.getAttribute(\"aria-expanded\")!==\"true\")}closeOnEscape(t){t.code===\"Escape\"&&(this.setExpanded(!1),this.btn.focus())}}customElements.define(\"starlight-menu-button\",s);"],["C:/Users/Harun/OneDrive/Desktop/my pc desktop/node_modules/@astrojs/starlight/components/Page.astro?astro&type=script&index=0&lang.ts","const a=document.getElementById(\"starlight__sidebar\"),n=a?.querySelector(\"sl-sidebar-state-persist\"),o=\"sl-sidebar-state\",i=()=>{let t=[];const e=n?.dataset.hash||\"\";try{const s=sessionStorage.getItem(o),r=JSON.parse(s||\"{}\");Array.isArray(r.open)&&r.hash===e&&(t=r.open)}catch{}return{hash:e,open:t,scroll:a?.scrollTop||0}},c=t=>{try{sessionStorage.setItem(o,JSON.stringify(t))}catch{}},d=()=>c(i()),l=(t,e)=>{const s=i();s.open[e]=t,c(s)};n?.addEventListener(\"click\",t=>{if(!(t.target instanceof Element))return;const e=t.target.closest(\"summary\")?.closest(\"details\");if(!e)return;const s=e.querySelector(\"sl-sidebar-restore\"),r=parseInt(s?.dataset.index||\"\");isNaN(r)||l(!e.open,r)});addEventListener(\"visibilitychange\",()=>{document.visibilityState===\"hidden\"&&d()});addEventListener(\"pageHide\",d);"],["C:/Users/Harun/OneDrive/Desktop/my pc desktop/node_modules/@astrojs/starlight/components/ThemeSelect.astro?astro&type=script&index=0&lang.ts","const r=\"starlight-theme\",o=e=>e===\"auto\"||e===\"dark\"||e===\"light\"?e:\"auto\",c=()=>o(typeof localStorage<\"u\"&&localStorage.getItem(r));function n(e){typeof localStorage<\"u\"&&localStorage.setItem(r,e===\"light\"||e===\"dark\"?e:\"\")}const l=()=>matchMedia(\"(prefers-color-scheme: light)\").matches?\"light\":\"dark\";function t(e){StarlightThemeProvider.updatePickers(e),document.documentElement.dataset.theme=e===\"auto\"?l():e,n(e)}matchMedia(\"(prefers-color-scheme: light)\").addEventListener(\"change\",()=>{c()===\"auto\"&&t(\"auto\")});class s extends HTMLElement{constructor(){super(),t(c()),this.querySelector(\"select\")?.addEventListener(\"change\",a=>{a.currentTarget instanceof HTMLSelectElement&&t(o(a.currentTarget.value))})}}customElements.define(\"starlight-theme-select\",s);"],["C:/Users/Harun/OneDrive/Desktop/my pc desktop/node_modules/@astrojs/starlight/user-components/Tabs.astro?astro&type=script&index=0&lang.ts","class r extends HTMLElement{static#e=new Map;#t;#n=\"starlight-synced-tabs__\";constructor(){super();const t=this.querySelector('[role=\"tablist\"]');if(this.tabs=[...t.querySelectorAll('[role=\"tab\"]')],this.panels=[...this.querySelectorAll(':scope > [role=\"tabpanel\"]')],this.#t=this.dataset.syncKey,this.#t){const i=r.#e.get(this.#t)??[];i.push(this),r.#e.set(this.#t,i)}this.tabs.forEach((i,c)=>{i.addEventListener(\"click\",e=>{e.preventDefault();const n=t.querySelector('[aria-selected=\"true\"]');e.currentTarget!==n&&this.switchTab(e.currentTarget,c)}),i.addEventListener(\"keydown\",e=>{const n=this.tabs.indexOf(e.currentTarget),s=e.key===\"ArrowLeft\"?n-1:e.key===\"ArrowRight\"?n+1:e.key===\"Home\"?0:e.key===\"End\"?this.tabs.length-1:null;s!==null&&this.tabs[s]&&(e.preventDefault(),this.switchTab(this.tabs[s],s))})})}switchTab(t,i,c=!0){if(!t)return;const e=c?this.getBoundingClientRect().top:0;this.tabs.forEach(s=>{s.setAttribute(\"aria-selected\",\"false\"),s.setAttribute(\"tabindex\",\"-1\")}),this.panels.forEach(s=>{s.hidden=!0});const n=this.panels[i];n&&(n.hidden=!1),t.removeAttribute(\"tabindex\"),t.setAttribute(\"aria-selected\",\"true\"),c&&(t.focus(),r.#r(this,t),window.scrollTo({top:window.scrollY+(this.getBoundingClientRect().top-e),behavior:\"instant\"}))}#i(t){!this.#t||typeof localStorage>\"u\"||localStorage.setItem(this.#n+this.#t,t)}static#r(t,i){const c=t.#t,e=r.#s(i);if(!c||!e)return;const n=r.#e.get(c);if(n){for(const s of n){if(s===t)continue;const a=s.tabs.findIndex(o=>r.#s(o)===e);a!==-1&&s.switchTab(s.tabs[a],a,!1)}t.#i(e)}}static#s(t){return t.textContent?.trim()}}customElements.define(\"starlight-tabs\",r);"]],"assets":["/_astro/houston.CZZyCf7p.webp","/_astro/print.DNXP8c50.css","/_astro/Code.BcHZMqfA.css","/_astro/common.DzFF2Dhy.css","/_astro/page.BIhdncjw.js","/file:///C:/Users/Harun/OneDrive/Desktop/my%20pc%20desktop/dist/404.html","/file:///C:/Users/Harun/OneDrive/Desktop/my%20pc%20desktop/dist/about/index.html","/file:///C:/Users/Harun/OneDrive/Desktop/my%20pc%20desktop/dist/articles/index.html","/file:///C:/Users/Harun/OneDrive/Desktop/my%20pc%20desktop/dist/contact/index.html","/file:///C:/Users/Harun/OneDrive/Desktop/my%20pc%20desktop/dist/index.html"],"i18n":{"fallbackType":"redirect","strategy":"pathname-prefix-other-locales","locales":["en"],"defaultLocale":"en","domainLookupTable":{}},"buildFormat":"directory","checkOrigin":false,"actionBodySizeLimit":1048576,"serverIslandBodySizeLimit":1048576,"allowedDomains":[],"key":"TyguYO0+DRnDzg7O3qqi9RO/OY9hU/2mh8LmFs6Iue4=","image":{},"devToolbar":{"enabled":false,"debugInfoOutput":""},"logLevel":"info","shouldInjectCspMetaTags":false}));
const manifestRoutes = _manifest.routes;
const manifest = Object.assign(_manifest, {
renderers,
actions: () => import('./noop-entrypoint_BOlrdqWF.mjs'),
middleware: () => import('./_virtual_astro_middleware_BNm4SpGT.mjs'),
sessionDriver: () => import('./_virtual_astro_session-driver_DYx9Bb3p.mjs'),
serverIslandMappings: () => import('./_virtual_astro_server-island-manifest_CQQ1F5PF.mjs'),
routes: manifestRoutes,
pageMap,
});
const VIRTUAL_PAGE_MODULE_ID = "virtual:astro:page:";
const VIRTUAL_PAGE_RESOLVED_MODULE_ID = "\0" + VIRTUAL_PAGE_MODULE_ID;
const ASTRO_PAGE_EXTENSION_POST_PATTERN = "@_@";
function getVirtualModulePageName(virtualModulePrefix, path) {
const extension = fileExtension(path);
return virtualModulePrefix + (extension.startsWith(".") ? path.slice(0, -extension.length) + extension.replace(".", ASTRO_PAGE_EXTENSION_POST_PATTERN) : path);
}
const SCRIPT_ID_PREFIX = `astro:scripts/`;
const BEFORE_HYDRATION_SCRIPT_ID = `${SCRIPT_ID_PREFIX}${"before-hydration"}.js`;
const PAGE_SCRIPT_ID = `${SCRIPT_ID_PREFIX}${"page"}.js`;
const ASTRO_PAGE_KEY_SEPARATOR = "&";
function makePageDataKey(route, componentPath) {
return route + ASTRO_PAGE_KEY_SEPARATOR + componentPath;
}
function getPageData(internals, route, component) {
let pageData = internals.pagesByKeys.get(makePageDataKey(route, component));
if (pageData) {
return pageData;
}
return void 0;
}
function cssOrder(a, b) {
let depthA = a.depth, depthB = b.depth, orderA = a.order, orderB = b.order;
if (orderA === -1 && orderB >= 0) {
return 1;
} else if (orderB === -1 && orderA >= 0) {
return -1;
} else if (orderA > orderB) {
return 1;
} else if (orderA < orderB) {
return -1;
} else {
if (depthA === -1) {
return -1;
} else if (depthB === -1) {
return 1;
} else {
return depthA > depthB ? -1 : 1;
}
}
}
function mergeInlineCss(acc, current) {
const lastAdded = acc.at(acc.length - 1);
const lastWasInline = lastAdded?.type === "inline";
const currentIsInline = current?.type === "inline";
if (lastWasInline && currentIsInline) {
const merged = { type: "inline", content: lastAdded.content + current.content };
acc[acc.length - 1] = merged;
return acc;
}
acc.push(current);
return acc;
}
class BuildPipeline extends Pipeline {
internals;
options;
manifest;
defaultRoutes;
getName() {
return "BuildPipeline";
}
/**
* This cache is needed to map a single `RouteData` to its file path.
* @private
*/
#routesByFilePath = /* @__PURE__ */ new WeakMap();
getSettings() {
if (!this.options) {
throw new Error("No options defined");
}
return this.options.settings;
}
getOptions() {
if (!this.options) {
throw new Error("No options defined");
}
return this.options;
}
getInternals() {
if (!this.internals) {
throw new Error("No internals defined");
}
return this.internals;
}
constructor(manifest, defaultRoutes = createDefaultRoutes(manifest)) {
const resolveCache = /* @__PURE__ */ new Map();
async function resolve(specifier) {
if (resolveCache.has(specifier)) {
return resolveCache.get(specifier);
}
const hashedFilePath = manifest.entryModules[specifier];
if (typeof hashedFilePath !== "string" || hashedFilePath === "") {
if (specifier === BEFORE_HYDRATION_SCRIPT_ID) {
resolveCache.set(specifier, "");
return "";
}
throw new Error(`Cannot find the built path for ${specifier}`);
}
const assetLink = createAssetLink(hashedFilePath, manifest.base, manifest.assetsPrefix);
resolveCache.set(specifier, assetLink);
return assetLink;
}
const logger = createConsoleLogger({ level: manifest.logLevel });
super(logger, manifest, "production", manifest.renderers, resolve, manifest.serverLike);
this.manifest = manifest;
this.defaultRoutes = defaultRoutes;
if (queueRenderingEnabled(this.manifest.experimentalQueuedRendering)) {
this.nodePool = newNodePool(this.manifest.experimentalQueuedRendering);
if (this.manifest.experimentalQueuedRendering.contentCache) {
this.htmlStringCache = new HTMLStringCache(1e3);
}
}
}
getRoutes() {
return this.getOptions().routesList.routes;
}
static create({ manifest }) {
return new BuildPipeline(manifest);
}
setInternals(internals) {
this.internals = internals;
}
setOptions(options) {
this.options = options;
}
headElements(routeData) {
const {
manifest: { assetsPrefix, base }
} = this;
const settings = this.getSettings();
const internals = this.getInternals();
const links = /* @__PURE__ */ new Set();
const pageBuildData = getPageData(internals, routeData.route, routeData.component);
const scripts = /* @__PURE__ */ new Set();
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") {
throw new Error(`Cannot find the built path for ${PAGE_SCRIPT_ID}`);
}
const src = createAssetLink(hashedFilePath, base, assetsPrefix);
scripts.add({
props: { type: "module", src },
children: ""
});
}
for (const script of settings.scripts) {
if (script.stage === "head-inline") {
scripts.add({
props: {},
children: script.content
});
}
}
return { scripts, styles, links };
}
componentMetadata() {
}
/**
* It collects the routes to generate during the build.
* It returns a map of page information and their relative entry point as a string.
*/
retrieveRoutesToGenerate() {
const pages = /* @__PURE__ */ new Set();
const defaultRouteComponents = new Set(this.defaultRoutes.map((route) => route.component));
for (const { routeData } of this.manifest.routes) {
if (routeIsRedirect(routeData)) {
pages.add(routeData);
continue;
}
if (routeIsFallback(routeData) && i18nHasFallback(this.manifest)) {
pages.add(routeData);
continue;
}
if (defaultRouteComponents.has(routeData.component)) {
continue;
}
pages.add(routeData);
const moduleSpecifier = getVirtualModulePageName(
VIRTUAL_PAGE_RESOLVED_MODULE_ID,
routeData.component
);
const filePath = this.internals?.entrySpecifierToBundleMap.get(moduleSpecifier);
if (filePath) {
this.#routesByFilePath.set(routeData, filePath);
}
}
return pages;
}
async getComponentByRoute(routeData) {
const module = await this.getModuleForRoute(routeData);
return module.page();
}
async getModuleForRoute(route) {
for (const defaultRoute of this.defaultRoutes) {
if (route.component === defaultRoute.component) {
return {
page: () => Promise.resolve(defaultRoute.instance)
};
}
}
let routeToProcess = route;
if (routeIsRedirect(route)) {
if (route.redirectRoute) {
routeToProcess = route.redirectRoute;
} else {
return RedirectSinglePageBuiltModule;
}
} else if (routeIsFallback(route)) {
routeToProcess = getFallbackRoute(route, this.manifest.routes);
}
if (this.manifest.pageMap) {
const importComponentInstance = this.manifest.pageMap.get(routeToProcess.component);
if (!importComponentInstance) {
throw new Error(
`Unexpectedly unable to find a component instance for route ${route.route}`
);
}
return await importComponentInstance();
} else if (this.manifest.pageModule) {
return this.manifest.pageModule;
}
throw new Error(
"Astro couldn't find the correct page to render, probably because it wasn't correctly mapped for SSR usage. This is an internal error, please file an issue."
);
}
async tryRewrite(payload, request) {
const { routeData, pathname, newUrl } = findRouteToRewrite({
payload,
request,
routes: this.manifest.routes.map((routeInfo) => routeInfo.routeData),
trailingSlash: this.manifest.trailingSlash,
buildFormat: this.manifest.buildFormat,
base: this.manifest.base,
outDir: this.manifest.serverLike ? this.manifest.buildClientDir : this.manifest.outDir
});
const componentInstance = await this.getComponentByRoute(routeData);
return { routeData, componentInstance, newUrl, pathname };
}
}
function i18nHasFallback(manifest) {
if (manifest.i18n && manifest.i18n.fallback) {
return Object.keys(manifest.i18n.fallback).length > 0;
}
return false;
}
class BuildApp extends BaseApp {
createPipeline(_streaming, manifest, ..._args) {
return BuildPipeline.create({
manifest
});
}
async createRenderContext(payload) {
return await super.createRenderContext({
...payload
});
}
isDev() {
return true;
}
setInternals(internals) {
this.pipeline.setInternals(internals);
}
setOptions(options) {
this.pipeline.setOptions(options);
this.logger.setDestination(options.logger.options.destination);
this.resetAdapterLogger();
}
getOptions() {
return this.pipeline.getOptions();
}
getSettings() {
return this.pipeline.getSettings();
}
async renderError(request, options) {
if (options.status === 500) {
if (options.response) {
return options.response;
}
throw options.error;
} else {
return super.renderError(request, {
...options,
prerenderedErrorPageFetch: void 0
});
}
}
getQueueStats() {
if (this.pipeline.nodePool) {
return this.pipeline.nodePool.getStats();
}
}
logRequest(_options) {
}
}
const app = new BuildApp(manifest);
export { AstroUserError as A, MissingSharp as B, createVNode as C, app as D, ExpectedImage as E, Fragment as F, manifest as G, ImageMissingAlt as I, LocalImageUsedWrongly as L, MissingImageDimension as M, NoImageMetadata as N, RenderUndefinedEntryError as R, UnknownContentCollectionError as U, __astro_tag_component__ as _, renderTemplate as a, addAttribute as b, renderHead as c, defineMiddleware as d, renderSlot as e, createRenderInstruction as f, AstroError as g, spreadAttributes as h, FontFamilyNotFound as i, defineStyleVars as j, renderElement$1 as k, generateCspDigest as l, maybeRenderHead as m, createHeadAndContent as n, InvalidComponentArgs as o, FailedToFetchRemoteImageDimensions as p, RemoteImageNotAllowed as q, renderComponent as r, sequence as s, UnsupportedImageFormat as t, unescapeHTML as u, IncompatibleDescriptorOptions as v, UnsupportedImageConversion as w, ExpectedImageOptions as x, ExpectedNotESMImage as y, InvalidImageService as z };