Initial commit

This commit is contained in:
Alejandro Martinez
2026-02-12 02:04:10 +01:00
commit f09af719cf
13433 changed files with 2193445 additions and 0 deletions

8
node_modules/astro/dist/core/routing/3xx.d.ts generated vendored Normal file
View File

@@ -0,0 +1,8 @@
type RedirectTemplate = {
from?: string;
absoluteLocation: string | URL;
status: number;
relativeLocation: string;
};
export declare function redirectTemplate({ status, absoluteLocation, relativeLocation, from, }: RedirectTemplate): string;
export {};

19
node_modules/astro/dist/core/routing/3xx.js generated vendored Normal file
View File

@@ -0,0 +1,19 @@
function redirectTemplate({
status,
absoluteLocation,
relativeLocation,
from
}) {
const delay = status === 302 ? 2 : 0;
return `<!doctype html>
<title>Redirecting to: ${relativeLocation}</title>
<meta http-equiv="refresh" content="${delay};url=${relativeLocation}">
<meta name="robots" content="noindex">
<link rel="canonical" href="${absoluteLocation}">
<body>
<a href="${relativeLocation}">Redirecting ${from ? `from <code>${from}</code> ` : ""}to <code>${relativeLocation}</code></a>
</body>`;
}
export {
redirectTemplate
};

View File

@@ -0,0 +1,5 @@
import type { ComponentInstance, RoutesList } from '../../types/astro.js';
import type { RouteData } from '../../types/public/internal.js';
export declare const DEFAULT_404_ROUTE: RouteData;
export declare function ensure404Route(manifest: RoutesList): RoutesList;
export declare const default404Instance: ComponentInstance;

View File

@@ -0,0 +1,42 @@
import notFoundTemplate from "../../template/4xx.js";
import { DEFAULT_404_COMPONENT } from "../constants.js";
const DEFAULT_404_ROUTE = {
component: DEFAULT_404_COMPONENT,
generate: () => "",
params: [],
pattern: /^\/404\/?$/,
prerender: false,
pathname: "/404",
segments: [[{ content: "404", dynamic: false, spread: false }]],
type: "page",
route: "/404",
fallbackRoutes: [],
isIndex: false,
origin: "internal"
};
function ensure404Route(manifest) {
if (!manifest.routes.some((route) => route.route === "/404")) {
manifest.routes.push(DEFAULT_404_ROUTE);
}
return manifest;
}
async function default404Page({ pathname }) {
return new Response(
notFoundTemplate({
statusCode: 404,
title: "Not found",
tabTitle: "404: Not Found",
pathname
}),
{ status: 404, headers: { "Content-Type": "text/html" } }
);
}
default404Page.isAstroComponentFactory = true;
const default404Instance = {
default: default404Page
};
export {
DEFAULT_404_ROUTE,
default404Instance,
ensure404Route
};

11
node_modules/astro/dist/core/routing/default.d.ts generated vendored Normal file
View File

@@ -0,0 +1,11 @@
import type { ComponentInstance } from '../../types/astro.js';
import type { SSRManifest } from '../app/types.js';
type DefaultRouteParams = {
instance: ComponentInstance;
matchesComponent(filePath: URL): boolean;
route: string;
component: string;
};
export declare const DEFAULT_COMPONENTS: string[];
export declare function createDefaultRoutes(manifest: SSRManifest): DefaultRouteParams[];
export {};

29
node_modules/astro/dist/core/routing/default.js generated vendored Normal file
View File

@@ -0,0 +1,29 @@
import { DEFAULT_404_COMPONENT } from "../constants.js";
import {
createEndpoint as createServerIslandEndpoint,
SERVER_ISLAND_COMPONENT,
SERVER_ISLAND_ROUTE
} from "../server-islands/endpoint.js";
import { DEFAULT_404_ROUTE, default404Instance } from "./astro-designed-error-pages.js";
const DEFAULT_COMPONENTS = [DEFAULT_404_COMPONENT, SERVER_ISLAND_COMPONENT];
function createDefaultRoutes(manifest) {
const root = new URL(manifest.hrefRoot);
return [
{
instance: default404Instance,
matchesComponent: (filePath) => filePath.href === new URL(DEFAULT_404_COMPONENT, root).href,
route: DEFAULT_404_ROUTE.route,
component: DEFAULT_404_COMPONENT
},
{
instance: createServerIslandEndpoint(manifest),
matchesComponent: (filePath) => filePath.href === new URL(SERVER_ISLAND_COMPONENT, root).href,
route: SERVER_ISLAND_ROUTE,
component: SERVER_ISLAND_COMPONENT
}
];
}
export {
DEFAULT_COMPONENTS,
createDefaultRoutes
};

3
node_modules/astro/dist/core/routing/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,3 @@
export { createRoutesList } from './manifest/create.js';
export { serializeRouteData } from './manifest/serialization.js';
export { matchAllRoutes } from './match.js';

8
node_modules/astro/dist/core/routing/index.js generated vendored Normal file
View File

@@ -0,0 +1,8 @@
import { createRoutesList } from "./manifest/create.js";
import { serializeRouteData } from "./manifest/serialization.js";
import { matchAllRoutes } from "./match.js";
export {
createRoutesList,
matchAllRoutes,
serializeRouteData
};

View File

@@ -0,0 +1,20 @@
import nodeFs from 'node:fs';
import type { AstroSettings, RoutesList } from '../../../types/astro.js';
import type { Logger } from '../../logger/core.js';
interface CreateRouteManifestParams {
/** Astro Settings object */
settings: AstroSettings;
/** Current working directory */
cwd?: string;
/** fs module, for testing */
fsMod?: typeof nodeFs;
}
/** Create manifest of all static routes */
export declare function createRoutesList(params: CreateRouteManifestParams, logger: Logger, { dev }?: {
dev?: boolean;
}): Promise<RoutesList>;
export declare function resolveInjectedRoute(entrypoint: string, root: URL, cwd?: string): {
resolved: string;
component: string;
};
export {};

539
node_modules/astro/dist/core/routing/manifest/create.js generated vendored Normal file
View File

@@ -0,0 +1,539 @@
import nodeFs from "node:fs";
import { createRequire } from "node:module";
import path from "node:path";
import { fileURLToPath } from "node:url";
import pLimit from "p-limit";
import colors from "piccolore";
import { injectImageEndpoint } from "../../../assets/endpoint/config.js";
import { toRoutingStrategy } from "../../../i18n/utils.js";
import { runHookRoutesResolved } from "../../../integrations/hooks.js";
import { getPrerenderDefault } from "../../../prerender/utils.js";
import { SUPPORTED_MARKDOWN_FILE_EXTENSIONS } from "../../constants.js";
import {
MissingIndexForInternationalization,
UnsupportedExternalRedirect
} from "../../errors/errors-data.js";
import { AstroError } from "../../errors/index.js";
import { hasFileExtension, removeLeadingForwardSlash, slash } from "../../path.js";
import { injectServerIslandRoute } from "../../server-islands/endpoint.js";
import { resolvePages } from "../../util.js";
import { ensure404Route } from "../astro-designed-error-pages.js";
import { routeComparator } from "../priority.js";
import { getRouteGenerator } from "./generator.js";
import { getPattern } from "./pattern.js";
import { getRoutePrerenderOption } from "./prerender.js";
import { validateSegment } from "./segment.js";
const require2 = createRequire(import.meta.url);
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 isSemanticallyEqualSegment(segmentA, segmentB) {
if (segmentA.length !== segmentB.length) {
return false;
}
for (const [index, partA] of segmentA.entries()) {
const partB = segmentB[index];
if (partA.dynamic !== partB.dynamic || partA.spread !== partB.spread) {
return false;
}
if (!partA.dynamic && partA.content !== partB.content) {
return false;
}
}
return true;
}
function createFileBasedRoutes({ settings, cwd, fsMod }, logger) {
const components = [];
const routes = [];
const validPageExtensions = /* @__PURE__ */ new Set([
".astro",
...SUPPORTED_MARKDOWN_FILE_EXTENSIONS,
...settings.pageExtensions
]);
const invalidPotentialPages = /* @__PURE__ */ new Set([".tsx", ".jsx", ".vue", ".svelte"]);
const validEndpointExtensions = /* @__PURE__ */ new Set([".js", ".ts"]);
const localFs = fsMod ?? nodeFs;
const prerender = getPrerenderDefault(settings.config);
function walk(fs, dir, parentSegments, parentParams) {
let items = [];
const files = fs.readdirSync(dir);
for (const basename of files) {
const resolved = path.join(dir, basename);
const file = slash(path.relative(cwd || fileURLToPath(settings.config.root), resolved));
const isDir = fs.statSync(resolved).isDirectory();
const ext = path.extname(basename);
const name = ext ? basename.slice(0, -ext.length) : basename;
if (name[0] === "_") {
continue;
}
if (basename[0] === "." && basename !== ".well-known") {
continue;
}
if (!isDir && !validPageExtensions.has(ext) && !validEndpointExtensions.has(ext)) {
if (invalidPotentialPages.has(ext)) {
logger.warn(
null,
`Unsupported file type ${colors.bold(
resolved
)} found in pages directory. Only Astro files can be used as pages. Prefix filename with an underscore (\`_\`) to ignore this warning, or move the file outside of the pages directory.`
);
}
continue;
}
const segment = isDir ? basename : name;
validateSegment(segment, file);
const parts = getParts(segment, file);
const isIndex = isDir ? false : basename.substring(0, basename.lastIndexOf(".")) === "index";
const routeSuffix = basename.slice(basename.indexOf("."), -ext.length);
const isPage = validPageExtensions.has(ext);
items.push({
basename,
ext,
parts,
file: file.replace(/\\/g, "/"),
isDir,
isIndex,
isPage,
routeSuffix
});
}
for (const item of items) {
const segments = parentSegments.slice();
if (item.isIndex) {
if (item.routeSuffix) {
if (segments.length > 0) {
const lastSegment = segments[segments.length - 1].slice();
const lastPart = lastSegment[lastSegment.length - 1];
if (lastPart.dynamic) {
lastSegment.push({
dynamic: false,
spread: false,
content: item.routeSuffix
});
} else {
lastSegment[lastSegment.length - 1] = {
dynamic: false,
spread: false,
content: `${lastPart.content}${item.routeSuffix}`
};
}
segments[segments.length - 1] = lastSegment;
} else {
segments.push(item.parts);
}
}
} else {
segments.push(item.parts);
}
const params = parentParams.slice();
params.push(...item.parts.filter((p) => p.dynamic).map((p) => p.content));
if (item.isDir) {
walk(fsMod ?? fs, path.join(dir, item.basename), segments, params);
} else {
components.push(item.file);
const component = item.file;
const pathname = segments.every((segment) => segment.length === 1 && !segment[0].dynamic) ? `/${segments.map((segment) => segment[0].content).join("/")}` : null;
const trailingSlash = trailingSlashForPath(pathname, settings.config);
const pattern = getPattern(segments, settings.config.base, trailingSlash);
const generate = getRouteGenerator(segments, trailingSlash);
const route = joinSegments(segments);
routes.push({
route,
isIndex: item.isIndex,
type: item.isPage ? "page" : "endpoint",
pattern,
segments,
params,
component,
generate,
pathname: pathname || void 0,
prerender,
fallbackRoutes: [],
distURL: [],
origin: "project"
});
}
}
}
const { config } = settings;
const pages = resolvePages(config);
if (localFs.existsSync(pages)) {
walk(localFs, fileURLToPath(pages), [], []);
} else if (settings.injectedRoutes.length === 0) {
const pagesDirRootRelative = pages.href.slice(settings.config.root.href.length);
logger.warn(null, `Missing pages directory: ${pagesDirRootRelative}`);
}
return routes;
}
const trailingSlashForPath = (pathname, config) => pathname && hasFileExtension(pathname) ? "ignore" : config.trailingSlash;
function createInjectedRoutes({ settings, cwd }) {
const { config } = settings;
const prerender = getPrerenderDefault(config);
const routes = [];
for (const injectedRoute of settings.injectedRoutes) {
const { pattern: name, entrypoint, prerender: prerenderInjected, origin } = injectedRoute;
const { resolved, component } = resolveInjectedRoute(entrypoint.toString(), config.root, cwd);
const segments = removeLeadingForwardSlash(name).split(path.posix.sep).filter(Boolean).map((s) => {
validateSegment(s);
return getParts(s, component);
});
const type = resolved.endsWith(".astro") ? "page" : "endpoint";
const pathname = segments.every((segment) => segment.length === 1 && !segment[0].dynamic) ? `/${segments.map((segment) => segment[0].content).join("/")}` : null;
const trailingSlash = trailingSlashForPath(pathname, config);
const pattern = getPattern(segments, settings.config.base, trailingSlash);
const generate = getRouteGenerator(segments, trailingSlash);
const params = segments.flat().filter((p) => p.dynamic).map((p) => p.content);
const route = joinSegments(segments);
routes.push({
type,
// For backwards compatibility, an injected route is never considered an index route.
isIndex: false,
route,
pattern,
segments,
params,
component,
generate,
pathname: pathname || void 0,
prerender: prerenderInjected ?? prerender,
fallbackRoutes: [],
distURL: [],
origin
});
}
return routes;
}
function createRedirectRoutes({ settings }, routeMap) {
const { config } = settings;
const trailingSlash = config.trailingSlash;
const routes = [];
for (const [from, to] of Object.entries(settings.config.redirects)) {
const segments = removeLeadingForwardSlash(from).split(path.posix.sep).filter(Boolean).map((s) => {
validateSegment(s);
return getParts(s, from);
});
const pattern = getPattern(segments, settings.config.base, trailingSlash);
const generate = getRouteGenerator(segments, trailingSlash);
const pathname = segments.every((segment) => segment.length === 1 && !segment[0].dynamic) ? `/${segments.map((segment) => segment[0].content).join("/")}` : null;
const params = segments.flat().filter((p) => p.dynamic).map((p) => p.content);
const route = joinSegments(segments);
let destination;
if (typeof to === "string") {
destination = to;
} else {
destination = to.destination;
}
if (URL.canParse(destination) && !/^https?:\/\//.test(destination)) {
throw new AstroError({
...UnsupportedExternalRedirect,
message: UnsupportedExternalRedirect.message(from, destination)
});
}
routes.push({
type: "redirect",
// For backwards compatibility, a redirect is never considered an index route.
isIndex: false,
route,
pattern,
segments,
params,
component: from,
generate,
pathname: pathname || void 0,
prerender: getPrerenderDefault(config),
redirect: to,
redirectRoute: routeMap.get(destination),
fallbackRoutes: [],
distURL: [],
origin: "project"
});
}
return routes;
}
function isStaticSegment(segment) {
return segment.every((part) => !part.dynamic && !part.spread);
}
function detectRouteCollision(a, b, _config, logger) {
if (a.type === "fallback" || b.type === "fallback") {
return;
}
if (a.route === b.route && a.segments.every(isStaticSegment) && b.segments.every(isStaticSegment)) {
logger.warn(
"router",
`The route "${a.route}" is defined in both "${a.component}" and "${b.component}". A static route cannot be defined more than once.`
);
logger.warn(
"router",
"A collision will result in an hard error in following versions of Astro."
);
return;
}
if (a.prerender || b.prerender) {
return;
}
if (a.segments.length !== b.segments.length) {
return;
}
const segmentCount = a.segments.length;
for (let index = 0; index < segmentCount; index++) {
const segmentA = a.segments[index];
const segmentB = b.segments[index];
if (!isSemanticallyEqualSegment(segmentA, segmentB)) {
return;
}
}
logger.warn(
"router",
`The route "${a.route}" is defined in both "${a.component}" and "${b.component}" using SSR mode. A dynamic SSR route cannot be defined more than once.`
);
logger.warn("router", "A collision will result in an hard error in following versions of Astro.");
}
async function createRoutesList(params, logger, { dev = false } = {}) {
const { settings } = params;
const { config } = settings;
const routeMap = /* @__PURE__ */ new Map();
const fileBasedRoutes = createFileBasedRoutes(params, logger);
for (const route of fileBasedRoutes) {
routeMap.set(route.route, route);
}
const injectedRoutes = createInjectedRoutes(params);
for (const route of injectedRoutes) {
routeMap.set(route.route, route);
}
const redirectRoutes = createRedirectRoutes(params, routeMap);
const filteredFiledBasedRoutes = fileBasedRoutes.filter((fileBasedRoute) => {
const isRedirect = redirectRoutes.findIndex((rd) => rd.route === fileBasedRoute.route);
return isRedirect < 0;
});
const routes = [
...[...filteredFiledBasedRoutes, ...injectedRoutes, ...redirectRoutes].sort(routeComparator)
];
settings.buildOutput = getPrerenderDefault(config) ? "static" : "server";
const limit = pLimit(10);
let promises = [];
for (const route of routes) {
promises.push(
limit(async () => {
if (route.type !== "page" && route.type !== "endpoint" && route.type !== "redirect") return;
if (route.type === "redirect" && !route.redirectRoute) return;
const localFs = params.fsMod ?? nodeFs;
const content = await localFs.promises.readFile(
fileURLToPath(
new URL(
// The destination redirect might be a prerendered
route.type === "redirect" && route.redirectRoute ? route.redirectRoute.component : route.component,
settings.config.root
)
),
"utf-8"
);
await getRoutePrerenderOption(content, route, settings, logger);
})
);
}
await Promise.all(promises);
for (const [index, higherRoute] of routes.entries()) {
for (const lowerRoute of routes.slice(index + 1)) {
detectRouteCollision(higherRoute, lowerRoute, config, logger);
}
}
const i18n = settings.config.i18n;
if (i18n) {
const strategy = toRoutingStrategy(i18n.routing, i18n.domains);
if (strategy === "pathname-prefix-always") {
let index = routes.find((route) => route.route === "/");
if (!index) {
let relativePath = path.relative(
fileURLToPath(settings.config.root),
fileURLToPath(new URL("pages", settings.config.srcDir))
);
throw new AstroError({
...MissingIndexForInternationalization,
message: MissingIndexForInternationalization.message(i18n.defaultLocale),
hint: MissingIndexForInternationalization.hint(relativePath)
});
}
}
const routesByLocale = /* @__PURE__ */ new Map();
const setRoutes = new Set(routes.filter((route) => route.type === "page"));
const filteredLocales = i18n.locales.filter((loc) => {
if (typeof loc === "string") {
return loc !== i18n.defaultLocale;
}
return loc.path !== i18n.defaultLocale;
}).map((locale) => {
if (typeof locale === "string") {
return locale;
}
return locale.path;
});
for (const locale of filteredLocales) {
for (const route of setRoutes) {
const hasLocaleInRoute = route.route.split("/").includes(locale);
if (!hasLocaleInRoute) {
continue;
}
const currentRoutes = routesByLocale.get(locale);
if (currentRoutes) {
currentRoutes.push(route);
routesByLocale.set(locale, currentRoutes);
} else {
routesByLocale.set(locale, [route]);
}
setRoutes.delete(route);
}
}
for (const route of setRoutes) {
const currentRoutes = routesByLocale.get(i18n.defaultLocale);
if (currentRoutes) {
currentRoutes.push(route);
routesByLocale.set(i18n.defaultLocale, currentRoutes);
} else {
routesByLocale.set(i18n.defaultLocale, [route]);
}
setRoutes.delete(route);
}
if (strategy === "pathname-prefix-always") {
const defaultLocaleRoutes = routesByLocale.get(i18n.defaultLocale);
if (defaultLocaleRoutes) {
const indexDefaultRoute = defaultLocaleRoutes.find(({ route }) => route === "/") ?? defaultLocaleRoutes.find(({ route }) => route === `/${i18n.defaultLocale}`);
if (indexDefaultRoute) {
const pathname = "/";
const route = "/";
const segments = removeLeadingForwardSlash(route).split(path.posix.sep).filter(Boolean).map((s) => {
validateSegment(s);
return getParts(s, route);
});
routes.push({
...indexDefaultRoute,
pathname,
route,
segments,
pattern: getPattern(segments, config.base, config.trailingSlash),
type: "fallback"
});
}
}
}
if (i18n.fallback) {
let fallback = Object.entries(i18n.fallback);
if (fallback.length > 0) {
for (const [fallbackFromLocale, fallbackToLocale] of fallback) {
let fallbackToRoutes;
if (fallbackToLocale === i18n.defaultLocale) {
fallbackToRoutes = routesByLocale.get(i18n.defaultLocale);
} else {
fallbackToRoutes = routesByLocale.get(fallbackToLocale);
}
const fallbackFromRoutes = routesByLocale.get(fallbackFromLocale);
if (!fallbackToRoutes) {
continue;
}
for (const fallbackToRoute of fallbackToRoutes) {
const hasRoute = fallbackFromRoutes && // we check if the fallback from locale (the origin) has already this route
fallbackFromRoutes.some((route) => {
if (fallbackToLocale === i18n.defaultLocale) {
return route.route === `/${fallbackFromLocale}${fallbackToRoute.route}` || route.route.replace(`/${fallbackFromLocale}`, "") === fallbackToRoute.route;
} else {
const expectedRoute = replaceOrKeep(
fallbackToRoute.route,
fallbackToLocale,
fallbackFromLocale
);
return route.route === expectedRoute;
}
});
if (!hasRoute) {
let pathname;
let route;
if (fallbackToLocale === i18n.defaultLocale && strategy === "pathname-prefix-other-locales") {
if (fallbackToRoute.pathname) {
pathname = `/${fallbackFromLocale}${fallbackToRoute.pathname}`;
}
route = `/${fallbackFromLocale}${fallbackToRoute.route}`;
} else {
pathname = fallbackToRoute.pathname ? replaceOrKeep(fallbackToRoute.pathname, fallbackToLocale, fallbackFromLocale) : void 0;
route = replaceOrKeep(fallbackToRoute.route, fallbackToLocale, fallbackFromLocale);
}
const segments = removeLeadingForwardSlash(route).split(path.posix.sep).filter(Boolean).map((s) => {
validateSegment(s);
return getParts(s, route);
});
const generate = getRouteGenerator(segments, config.trailingSlash);
const index = routes.findIndex((r) => r === fallbackToRoute);
if (index >= 0) {
const fallbackRoute = {
...fallbackToRoute,
pathname,
route,
segments,
generate,
pattern: getPattern(segments, config.base, config.trailingSlash),
type: "fallback",
fallbackRoutes: []
};
const routeData = routes[index];
routeData.fallbackRoutes.push(fallbackRoute);
}
}
}
}
}
}
}
if (dev) {
ensure404Route({ routes });
}
if (dev || settings.buildOutput === "server") {
injectImageEndpoint(settings, { routes }, dev ? "dev" : "build");
}
if (dev || settings.config.adapter) {
injectServerIslandRoute(settings.config, { routes });
}
await runHookRoutesResolved({ routes, settings, logger });
return {
routes
};
}
function resolveInjectedRoute(entrypoint, root, cwd) {
let resolved;
try {
resolved = require2.resolve(entrypoint, { paths: [cwd || fileURLToPath(root)] });
} catch {
resolved = fileURLToPath(new URL(entrypoint, root));
}
return {
resolved,
component: slash(path.relative(cwd || fileURLToPath(root), resolved))
};
}
function joinSegments(segments) {
const arr = segments.map((segment) => {
return segment.map((rp) => rp.dynamic ? `[${rp.content}]` : rp.content).join("");
});
return `/${arr.join("/")}`.toLowerCase();
}
function replaceOrKeep(original, from, to) {
if (original.startsWith(`/${to}/`) || original === `/${to}`) return original;
return original.replace(`/${from}/`, `/${to}/`).replace(`/${from}`, `/${to}`);
}
export {
createRoutesList,
resolveInjectedRoute
};

View File

@@ -0,0 +1,3 @@
import type { AstroConfig } from '../../../types/public/config.js';
import type { RoutePart } from '../../../types/public/internal.js';
export declare function getRouteGenerator(segments: RoutePart[][], addTrailingSlash: AstroConfig['trailingSlash']): (params: Record<string, string | number>) => string;

View File

@@ -0,0 +1,40 @@
function sanitizeParams(params) {
return Object.fromEntries(
Object.entries(params).map(([key, value]) => {
if (typeof value === "string") {
return [key, value.normalize().replace(/#/g, "%23").replace(/\?/g, "%3F")];
}
return [key, value];
})
);
}
function getParameter(part, params) {
if (part.spread) {
return params[part.content.slice(3)] || "";
}
if (part.dynamic) {
if (!params[part.content]) {
throw new TypeError(`Missing parameter: ${part.content}`);
}
return params[part.content];
}
return part.content.normalize().replace(/\?/g, "%3F").replace(/#/g, "%23").replace(/%5B/g, "[").replace(/%5D/g, "]");
}
function getSegment(segment, params) {
const segmentPath = segment.map((part) => getParameter(part, params)).join("");
return segmentPath ? "/" + segmentPath : "";
}
function getRouteGenerator(segments, addTrailingSlash) {
return (params) => {
const sanitizedParams = sanitizeParams(params);
let trailing = "";
if (addTrailingSlash === "always" && segments.length) {
trailing = "/";
}
const path = segments.map((segment) => getSegment(segment, sanitizedParams)).join("") + trailing;
return path || "/";
};
}
export {
getRouteGenerator
};

View File

@@ -0,0 +1,2 @@
import type { RoutePart } from '../../../types/public/index.js';
export declare function getParts(part: string, file: string): RoutePart[];

22
node_modules/astro/dist/core/routing/manifest/parts.js generated vendored Normal file
View File

@@ -0,0 +1,22 @@
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;
}
export {
getParts
};

View File

@@ -0,0 +1,3 @@
import type { AstroConfig } from '../../../types/public/config.js';
import type { RoutePart } from '../../../types/public/internal.js';
export declare function getPattern(segments: RoutePart[][], base: AstroConfig['base'], addTrailingSlash: AstroConfig['trailingSlash']): RegExp;

View File

@@ -0,0 +1,35 @@
function getPattern(segments, base, addTrailingSlash) {
const pathname = segments.map((segment) => {
if (segment.length === 1 && segment[0].spread) {
return "(?:\\/(.*?))?";
} else {
return "\\/" + segment.map((part) => {
if (part.spread) {
return "(.*?)";
} else if (part.dynamic) {
return "([^/]+?)";
} else {
return part.content.normalize().replace(/\?/g, "%3F").replace(/#/g, "%23").replace(/%5B/g, "[").replace(/%5D/g, "]").replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
}).join("");
}
}).join("");
const trailing = addTrailingSlash && segments.length ? getTrailingSlashPattern(addTrailingSlash) : "$";
let initial = "\\/";
if (addTrailingSlash === "never" && base !== "/") {
initial = "";
}
return new RegExp(`^${pathname || initial}${trailing}`);
}
function getTrailingSlashPattern(addTrailingSlash) {
if (addTrailingSlash === "always") {
return "\\/$";
}
if (addTrailingSlash === "never") {
return "$";
}
return "\\/?$";
}
export {
getPattern
};

View File

@@ -0,0 +1,4 @@
import type { AstroSettings } from '../../../types/astro.js';
import type { RouteData } from '../../../types/public/internal.js';
import type { Logger } from '../../logger/core.js';
export declare function getRoutePrerenderOption(content: string, route: RouteData, settings: AstroSettings, logger: Logger): Promise<void>;

View File

@@ -0,0 +1,20 @@
import { runHookRouteSetup } from "../../../integrations/hooks.js";
import { getPrerenderDefault } from "../../../prerender/utils.js";
const PRERENDER_REGEX = /^\s*export\s+const\s+prerender\s*=\s*(true|false);?/m;
async function getRoutePrerenderOption(content, route, settings, logger) {
const match = PRERENDER_REGEX.exec(content);
if (match) {
route.prerender = match[1] === "true";
if (route.redirectRoute) {
route.redirectRoute.prerender = match[1] === "true";
}
}
await runHookRouteSetup({ route, settings, logger });
if (typeof route.prerender === void 0) {
route.prerender = getPrerenderDefault(settings.config);
}
if (!route.prerender) settings.buildOutput = "server";
}
export {
getRoutePrerenderOption
};

View File

@@ -0,0 +1 @@
export declare function validateSegment(segment: string, file?: string): void;

View File

@@ -0,0 +1,22 @@
function validateSegment(segment, file = "") {
if (!file) file = segment;
if (segment.includes("][")) {
throw new Error(`Invalid route ${file} \u2014 parameters must be separated`);
}
if (countOccurrences("[", segment) !== countOccurrences("]", segment)) {
throw new Error(`Invalid route ${file} \u2014 brackets are unbalanced`);
}
if ((/.+\[\.\.\.[^\]]+\]/.test(segment) || /\[\.\.\.[^\]]+\].+/.test(segment)) && file.endsWith(".astro")) {
throw new Error(`Invalid route ${file} \u2014 rest parameter must be a standalone segment`);
}
}
function countOccurrences(needle, haystack) {
let count = 0;
for (const hay of haystack) {
if (hay === needle) count += 1;
}
return count;
}
export {
validateSegment
};

View File

@@ -0,0 +1,5 @@
import type { SerializedRouteData } from '../../../types/astro.js';
import type { AstroConfig } from '../../../types/public/config.js';
import type { RouteData } from '../../../types/public/internal.js';
export declare function serializeRouteData(routeData: RouteData, trailingSlash: AstroConfig['trailingSlash']): SerializedRouteData;
export declare function deserializeRouteData(rawRouteData: SerializedRouteData): RouteData;

View File

@@ -0,0 +1,37 @@
import { getRouteGenerator } from "./generator.js";
function serializeRouteData(routeData, trailingSlash) {
return {
...routeData,
generate: void 0,
pattern: routeData.pattern.source,
redirectRoute: routeData.redirectRoute ? serializeRouteData(routeData.redirectRoute, trailingSlash) : void 0,
fallbackRoutes: routeData.fallbackRoutes.map((fallbackRoute) => {
return serializeRouteData(fallbackRoute, trailingSlash);
}),
_meta: { trailingSlash }
};
}
function deserializeRouteData(rawRouteData) {
return {
route: rawRouteData.route,
type: rawRouteData.type,
pattern: new RegExp(rawRouteData.pattern),
params: rawRouteData.params,
component: rawRouteData.component,
generate: getRouteGenerator(rawRouteData.segments, rawRouteData._meta.trailingSlash),
pathname: rawRouteData.pathname || void 0,
segments: rawRouteData.segments,
prerender: rawRouteData.prerender,
redirect: rawRouteData.redirect,
redirectRoute: rawRouteData.redirectRoute ? deserializeRouteData(rawRouteData.redirectRoute) : void 0,
fallbackRoutes: rawRouteData.fallbackRoutes.map((fallback) => {
return deserializeRouteData(fallback);
}),
isIndex: rawRouteData.isIndex,
origin: rawRouteData.origin
};
}
export {
deserializeRouteData,
serializeRouteData
};

45
node_modules/astro/dist/core/routing/match.d.ts generated vendored Normal file
View File

@@ -0,0 +1,45 @@
import type { RoutesList } from '../../types/astro.js';
import type { RouteData } from '../../types/public/internal.js';
/** Find matching route from pathname */
export declare function matchRoute(pathname: string, manifest: RoutesList): RouteData | undefined;
/** Finds all matching routes from pathname */
export declare function matchAllRoutes(pathname: string, manifest: RoutesList): RouteData[];
export declare function isRoute404(route: string): boolean;
export declare function isRoute500(route: string): boolean;
/**
* Determines if the given route matches a 404 or 500 error page.
*
* @param {RouteData} route - The route data to check.
* @returns {boolean} `true` if the route matches a 404 or 500 error page, otherwise `false`.
*/
export declare function isRoute404or500(route: RouteData): boolean;
/**
* Determines if a given route is associated with the server island component.
*
* @param {RouteData} route - The route data object to evaluate.
* @return {boolean} Returns true if the route's component is the server island component, otherwise false.
*/
export declare function isRouteServerIsland(route: RouteData): boolean;
/**
* Determines whether the given `Request` is targeted to a "server island" based on its URL.
*
* @param {Request} request - The request object to be evaluated.
* @param {string} [base=''] - The base path provided via configuration.
* @return {boolean} - Returns `true` if the request is for a server island, otherwise `false`.
*/
export declare function isRequestServerIsland(request: Request, base?: string): boolean;
/**
* Checks if the given request corresponds to a 404 or 500 route based on the specified base path.
*
* @param {Request} request - The HTTP request object to be checked.
* @param {string} [base=''] - The base path to trim from the request's URL before checking the route. Default is an empty string.
* @return {boolean} Returns true if the request matches a 404 or 500 route; otherwise, returns false.
*/
export declare function requestIs404Or500(request: Request, base?: string): boolean;
/**
* Determines whether a given route is an external redirect.
*
* @param {RouteData} route - The route object to check.
* @return {boolean} Returns true if the route is an external redirect, otherwise false.
*/
export declare function isRouteExternalRedirect(route: RouteData): boolean;

48
node_modules/astro/dist/core/routing/match.js generated vendored Normal file
View File

@@ -0,0 +1,48 @@
import { redirectIsExternal } from "../redirects/render.js";
import { SERVER_ISLAND_BASE_PREFIX, SERVER_ISLAND_COMPONENT } from "../server-islands/endpoint.js";
function matchRoute(pathname, manifest) {
return manifest.routes.find((route) => {
return route.pattern.test(pathname) || route.fallbackRoutes.some((fallbackRoute) => fallbackRoute.pattern.test(pathname));
});
}
function matchAllRoutes(pathname, manifest) {
return manifest.routes.filter((route) => route.pattern.test(pathname));
}
const ROUTE404_RE = /^\/404\/?$/;
const ROUTE500_RE = /^\/500\/?$/;
function isRoute404(route) {
return ROUTE404_RE.test(route);
}
function isRoute500(route) {
return ROUTE500_RE.test(route);
}
function isRoute404or500(route) {
return isRoute404(route.route) || isRoute500(route.route);
}
function isRouteServerIsland(route) {
return route.component === SERVER_ISLAND_COMPONENT;
}
function isRequestServerIsland(request, base = "") {
const url = new URL(request.url);
const pathname = base === "/" ? url.pathname.slice(base.length) : url.pathname.slice(base.length + 1);
return pathname.startsWith(SERVER_ISLAND_BASE_PREFIX);
}
function requestIs404Or500(request, base = "") {
const url = new URL(request.url);
const pathname = url.pathname.slice(base.length);
return isRoute404(pathname) || isRoute500(pathname);
}
function isRouteExternalRedirect(route) {
return !!(route.type === "redirect" && route.redirect && redirectIsExternal(route.redirect));
}
export {
isRequestServerIsland,
isRoute404,
isRoute404or500,
isRoute500,
isRouteExternalRedirect,
isRouteServerIsland,
matchAllRoutes,
matchRoute,
requestIs404Or500
};

8
node_modules/astro/dist/core/routing/params.d.ts generated vendored Normal file
View File

@@ -0,0 +1,8 @@
import type { GetStaticPathsItem } from '../../types/public/common.js';
import type { RouteData } from '../../types/public/internal.js';
/**
* given a route's Params object, validate parameter
* values and create a stringified key for the route
* that can be used to match request routes
*/
export declare function stringifyParams(params: GetStaticPathsItem['params'], route: RouteData): string;

16
node_modules/astro/dist/core/routing/params.js generated vendored Normal file
View File

@@ -0,0 +1,16 @@
import { trimSlashes } from "../path.js";
import { validateGetStaticPathsParameter } from "./validation.js";
function stringifyParams(params, route) {
const validatedParams = Object.entries(params).reduce((acc, next) => {
validateGetStaticPathsParameter(next, route.component);
const [key, value] = next;
if (value !== void 0) {
acc[key] = typeof value === "string" ? trimSlashes(value) : value.toString();
}
return acc;
}, {});
return route.generate(validatedParams);
}
export {
stringifyParams
};

23
node_modules/astro/dist/core/routing/priority.d.ts generated vendored Normal file
View File

@@ -0,0 +1,23 @@
import type { RouteData } from '../../types/public/internal.js';
/**
* Comparator for sorting routes in resolution order.
*
* The routes are sorted in by the following rules in order, following the first rule that
* applies:
* - More specific routes are sorted before less specific routes. Here, "specific" means
* the number of segments in the route, so a parent route is always sorted after its children.
* For example, `/foo/bar` is sorted before `/foo`.
* Index routes, originating from a file named `index.astro`, are considered to have one more
* segment than the URL they represent.
* - Static routes are sorted before dynamic routes.
* For example, `/foo/bar` is sorted before `/foo/[bar]`.
* - Dynamic routes with single parameters are sorted before dynamic routes with rest parameters.
* For example, `/foo/[bar]` is sorted before `/foo/[...bar]`.
* - Prerendered routes are sorted before non-prerendered routes.
* - Endpoints are sorted before pages.
* For example, a file `/foo.ts` is sorted before `/bar.astro`.
* - If both routes are equal regarding all previous conditions, they are sorted alphabetically.
* For example, `/bar` is sorted before `/foo`.
* The definition of "alphabetically" is dependent on the default locale of the running system.
*/
export declare function routeComparator(a: RouteData, b: RouteData): number;

51
node_modules/astro/dist/core/routing/priority.js generated vendored Normal file
View File

@@ -0,0 +1,51 @@
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);
}
export {
routeComparator
};

9
node_modules/astro/dist/core/routing/request.d.ts generated vendored Normal file
View File

@@ -0,0 +1,9 @@
/**
* Utilities for extracting information from `Request`
*/
/**
* Returns the first value associated to the `x-forwarded-for` header.
*
* @param {Request} request
*/
export declare function getClientIpAddress(request: Request): string | undefined;

9
node_modules/astro/dist/core/routing/request.js generated vendored Normal file
View File

@@ -0,0 +1,9 @@
function getFirstForwardedValue(multiValueHeader) {
return multiValueHeader?.toString()?.split(",").map((e) => e.trim())?.[0];
}
function getClientIpAddress(request) {
return getFirstForwardedValue(request.headers.get("x-forwarded-for"));
}
export {
getClientIpAddress
};

37
node_modules/astro/dist/core/routing/rewrite.d.ts generated vendored Normal file
View File

@@ -0,0 +1,37 @@
import type { RewritePayload } from '../../types/public/common.js';
import type { AstroConfig } from '../../types/public/config.js';
import type { RouteData } from '../../types/public/internal.js';
import type { Logger } from '../logger/core.js';
type FindRouteToRewrite = {
payload: RewritePayload;
routes: RouteData[];
request: Request;
trailingSlash: AstroConfig['trailingSlash'];
buildFormat: AstroConfig['build']['format'];
base: AstroConfig['base'];
outDir: URL | string;
};
interface FindRouteToRewriteResult {
routeData: RouteData;
newUrl: URL;
pathname: string;
}
/**
* Shared logic to retrieve the rewritten route. It returns a tuple that represents:
* 1. The new `Request` object. It contains `base`
* 2.
*/
export declare function findRouteToRewrite({ payload, routes, request, trailingSlash, buildFormat, base, outDir, }: FindRouteToRewrite): FindRouteToRewriteResult;
/**
* Utility function that creates a new `Request` with a new URL from an old `Request`.
*
* @param newUrl The new `URL`
* @param oldRequest The old `Request`
* @param isPrerendered It needs to be the flag of the previous routeData, before the rewrite
* @param logger
* @param routePattern
*/
export declare function copyRequest(newUrl: URL, oldRequest: Request, isPrerendered: boolean, logger: Logger, routePattern: string): Request;
export declare function setOriginPathname(request: Request, pathname: string, trailingSlash: AstroConfig['trailingSlash'], buildFormat: AstroConfig['build']['format']): void;
export declare function getOriginPathname(request: Request): string;
export {};

140
node_modules/astro/dist/core/routing/rewrite.js generated vendored Normal file
View File

@@ -0,0 +1,140 @@
import { shouldAppendForwardSlash } from "../build/util.js";
import { originPathnameSymbol } from "../constants.js";
import { AstroError, AstroErrorData } from "../errors/index.js";
import {
appendForwardSlash,
joinPaths,
prependForwardSlash,
removeTrailingForwardSlash,
trimSlashes
} from "../path.js";
import { createRequest } from "../request.js";
import { DEFAULT_404_ROUTE } from "./astro-designed-error-pages.js";
function findRouteToRewrite({
payload,
routes,
request,
trailingSlash,
buildFormat,
base,
outDir
}) {
let newUrl = void 0;
if (payload instanceof URL) {
newUrl = payload;
} else if (payload instanceof Request) {
newUrl = new URL(payload.url);
} else {
newUrl = new URL(payload, new URL(request.url).origin);
}
let pathname = newUrl.pathname;
const shouldAppendSlash = shouldAppendForwardSlash(trailingSlash, buildFormat);
if (base !== "/") {
const isBasePathRequest = newUrl.pathname === base || newUrl.pathname === removeTrailingForwardSlash(base);
if (isBasePathRequest) {
pathname = shouldAppendSlash ? "/" : "";
} else if (newUrl.pathname.startsWith(base)) {
pathname = shouldAppendSlash ? appendForwardSlash(newUrl.pathname) : removeTrailingForwardSlash(newUrl.pathname);
pathname = pathname.slice(base.length);
}
}
if (!pathname.startsWith("/") && shouldAppendSlash && newUrl.pathname.endsWith("/")) {
pathname = prependForwardSlash(pathname);
}
if (pathname === "/" && base !== "/" && !shouldAppendSlash) {
pathname = "";
}
if (buildFormat === "file") {
pathname = pathname.replace(/\.html$/, "");
}
if (base !== "/" && (pathname === "" || pathname === "/") && !shouldAppendSlash) {
newUrl.pathname = removeTrailingForwardSlash(base);
} else {
newUrl.pathname = joinPaths(...[base, pathname].filter(Boolean));
}
const decodedPathname = decodeURI(pathname);
let foundRoute;
for (const route of routes) {
if (route.pattern.test(decodedPathname)) {
if (route.params && route.params.length !== 0 && route.distURL && route.distURL.length !== 0) {
if (!route.distURL.find(
(url) => url.href.replace(outDir.toString(), "").replace(/(?:\/index\.html|\.html)$/, "") == trimSlashes(decodedPathname)
)) {
continue;
}
}
foundRoute = route;
break;
}
}
if (foundRoute) {
return {
routeData: foundRoute,
newUrl,
pathname: decodedPathname
};
} else {
const custom404 = routes.find((route) => route.route === "/404");
if (custom404) {
return { routeData: custom404, newUrl, pathname };
} else {
return { routeData: DEFAULT_404_ROUTE, newUrl, pathname };
}
}
}
function copyRequest(newUrl, oldRequest, isPrerendered, logger, routePattern) {
if (oldRequest.bodyUsed) {
throw new AstroError(AstroErrorData.RewriteWithBodyUsed);
}
return createRequest({
url: newUrl,
method: oldRequest.method,
body: oldRequest.body,
isPrerendered,
logger,
headers: isPrerendered ? {} : oldRequest.headers,
routePattern,
init: {
referrer: oldRequest.referrer,
referrerPolicy: oldRequest.referrerPolicy,
mode: oldRequest.mode,
credentials: oldRequest.credentials,
cache: oldRequest.cache,
redirect: oldRequest.redirect,
integrity: oldRequest.integrity,
signal: oldRequest.signal,
keepalive: oldRequest.keepalive,
// https://fetch.spec.whatwg.org/#dom-request-duplex
// @ts-expect-error It isn't part of the types, but undici accepts it and it allows to carry over the body to a new request
duplex: "half"
}
});
}
function setOriginPathname(request, pathname, trailingSlash, buildFormat) {
if (!pathname) {
pathname = "/";
}
const shouldAppendSlash = shouldAppendForwardSlash(trailingSlash, buildFormat);
let finalPathname;
if (pathname === "/") {
finalPathname = "/";
} else if (shouldAppendSlash) {
finalPathname = appendForwardSlash(pathname);
} else {
finalPathname = removeTrailingForwardSlash(pathname);
}
Reflect.set(request, originPathnameSymbol, encodeURIComponent(finalPathname));
}
function getOriginPathname(request) {
const origin = Reflect.get(request, originPathnameSymbol);
if (origin) {
return decodeURIComponent(origin);
}
return new URL(request.url).pathname;
}
export {
copyRequest,
findRouteToRewrite,
getOriginPathname,
setOriginPathname
};

13
node_modules/astro/dist/core/routing/validation.d.ts generated vendored Normal file
View File

@@ -0,0 +1,13 @@
import type { ComponentInstance } from '../../types/astro.js';
import type { GetStaticPathsResult } from '../../types/public/common.js';
import type { RouteData } from '../../types/public/internal.js';
import type { Logger } from '../logger/core.js';
/** Throws error for invalid parameter in getStaticPaths() response */
export declare function validateGetStaticPathsParameter([key, value]: [string, any], route: string): void;
/** Error for deprecated or malformed route components */
export declare function validateDynamicRouteModule(mod: ComponentInstance, { ssr, route, }: {
ssr: boolean;
route: RouteData;
}): void;
/** Throw error and log warnings for malformed getStaticPaths() response */
export declare function validateGetStaticPathsResult(result: GetStaticPathsResult, logger: Logger, route: RouteData): void;

74
node_modules/astro/dist/core/routing/validation.js generated vendored Normal file
View File

@@ -0,0 +1,74 @@
import { AstroError, AstroErrorData } from "../errors/index.js";
const VALID_PARAM_TYPES = ["string", "number", "undefined"];
function validateGetStaticPathsParameter([key, value], route) {
if (!VALID_PARAM_TYPES.includes(typeof value)) {
throw new AstroError({
...AstroErrorData.GetStaticPathsInvalidRouteParam,
message: AstroErrorData.GetStaticPathsInvalidRouteParam.message(key, value, typeof value),
location: {
file: route
}
});
}
}
function validateDynamicRouteModule(mod, {
ssr,
route
}) {
if ((!ssr || route.prerender) && !mod.getStaticPaths) {
throw new AstroError({
...AstroErrorData.GetStaticPathsRequired,
location: { file: route.component }
});
}
}
function validateGetStaticPathsResult(result, logger, route) {
if (!Array.isArray(result)) {
throw new AstroError({
...AstroErrorData.InvalidGetStaticPathsReturn,
message: AstroErrorData.InvalidGetStaticPathsReturn.message(typeof result),
location: {
file: route.component
}
});
}
result.forEach((pathObject) => {
if (typeof pathObject === "object" && Array.isArray(pathObject) || pathObject === null) {
throw new AstroError({
...AstroErrorData.InvalidGetStaticPathsEntry,
message: AstroErrorData.InvalidGetStaticPathsEntry.message(
Array.isArray(pathObject) ? "array" : typeof pathObject
)
});
}
if (pathObject.params === void 0 || pathObject.params === null || pathObject.params && Object.keys(pathObject.params).length === 0) {
throw new AstroError({
...AstroErrorData.GetStaticPathsExpectedParams,
location: {
file: route.component
}
});
}
for (const [key, val] of Object.entries(pathObject.params)) {
if (!(typeof val === "undefined" || typeof val === "string" || typeof val === "number")) {
logger.warn(
"router",
`getStaticPaths() returned an invalid path param: "${key}". A string, number or undefined value was expected, but got \`${JSON.stringify(
val
)}\`.`
);
}
if (typeof val === "string" && val === "") {
logger.warn(
"router",
`getStaticPaths() returned an invalid path param: "${key}". \`undefined\` expected for an optional param, but got empty string.`
);
}
}
});
}
export {
validateDynamicRouteModule,
validateGetStaticPathsParameter,
validateGetStaticPathsResult
};