Refactor routing in App component to enhance navigation and improve error handling by integrating dynamic routes and updating the NotFound route.

This commit is contained in:
becarta
2025-05-23 12:43:00 +02:00
parent f40db0f5c9
commit a544759a3b
11127 changed files with 1647032 additions and 0 deletions

5
node_modules/astro/dist/jsx/babel.d.ts generated vendored Normal file
View File

@@ -0,0 +1,5 @@
import type { PluginObj } from '@babel/core';
/**
* @deprecated This plugin is no longer used. Remove in Astro 5.0
*/
export default function astroJSX(): PluginObj;

287
node_modules/astro/dist/jsx/babel.js generated vendored Normal file
View File

@@ -0,0 +1,287 @@
import * as t from "@babel/types";
import { AstroError } from "../core/errors/errors.js";
import { AstroErrorData } from "../core/errors/index.js";
import { resolvePath } from "../core/viteUtils.js";
import { createDefaultAstroMetadata } from "../vite-plugin-astro/metadata.js";
const ClientOnlyPlaceholder = "astro-client-only";
function isComponent(tagName) {
return tagName[0] && tagName[0].toLowerCase() !== tagName[0] || tagName.includes(".") || /[^a-zA-Z]/.test(tagName[0]);
}
function hasClientDirective(node) {
for (const attr of node.openingElement.attributes) {
if (attr.type === "JSXAttribute" && attr.name.type === "JSXNamespacedName") {
return attr.name.namespace.name === "client";
}
}
return false;
}
function isClientOnlyComponent(node) {
for (const attr of node.openingElement.attributes) {
if (attr.type === "JSXAttribute" && attr.name.type === "JSXNamespacedName") {
return jsxAttributeToString(attr) === "client:only";
}
}
return false;
}
function getTagName(tag) {
const jsxName = tag.openingElement.name;
return jsxElementNameToString(jsxName);
}
function jsxElementNameToString(node) {
if (t.isJSXMemberExpression(node)) {
return `${jsxElementNameToString(node.object)}.${node.property.name}`;
}
if (t.isJSXIdentifier(node) || t.isIdentifier(node)) {
return node.name;
}
return `${node.namespace.name}:${node.name.name}`;
}
function jsxAttributeToString(attr) {
if (t.isJSXNamespacedName(attr.name)) {
return `${attr.name.namespace.name}:${attr.name.name.name}`;
}
return `${attr.name.name}`;
}
function addClientMetadata(node, meta) {
const existingAttributes = node.openingElement.attributes.map(
(attr) => t.isJSXAttribute(attr) ? jsxAttributeToString(attr) : null
);
if (!existingAttributes.find((attr) => attr === "client:component-path")) {
const componentPath = t.jsxAttribute(
t.jsxNamespacedName(t.jsxIdentifier("client"), t.jsxIdentifier("component-path")),
t.stringLiteral(meta.resolvedPath)
);
node.openingElement.attributes.push(componentPath);
}
if (!existingAttributes.find((attr) => attr === "client:component-export")) {
if (meta.name === "*") {
meta.name = getTagName(node).split(".").slice(1).join(".");
}
const componentExport = t.jsxAttribute(
t.jsxNamespacedName(t.jsxIdentifier("client"), t.jsxIdentifier("component-export")),
t.stringLiteral(meta.name)
);
node.openingElement.attributes.push(componentExport);
}
if (!existingAttributes.find((attr) => attr === "client:component-hydration")) {
const staticMarker = t.jsxAttribute(
t.jsxNamespacedName(t.jsxIdentifier("client"), t.jsxIdentifier("component-hydration"))
);
node.openingElement.attributes.push(staticMarker);
}
}
function addClientOnlyMetadata(node, meta) {
const tagName = getTagName(node);
node.openingElement = t.jsxOpeningElement(
t.jsxIdentifier(ClientOnlyPlaceholder),
node.openingElement.attributes
);
if (node.closingElement) {
node.closingElement = t.jsxClosingElement(t.jsxIdentifier(ClientOnlyPlaceholder));
}
const existingAttributes = node.openingElement.attributes.map(
(attr) => t.isJSXAttribute(attr) ? jsxAttributeToString(attr) : null
);
if (!existingAttributes.find((attr) => attr === "client:display-name")) {
const displayName = t.jsxAttribute(
t.jsxNamespacedName(t.jsxIdentifier("client"), t.jsxIdentifier("display-name")),
t.stringLiteral(tagName)
);
node.openingElement.attributes.push(displayName);
}
if (!existingAttributes.find((attr) => attr === "client:component-path")) {
const componentPath = t.jsxAttribute(
t.jsxNamespacedName(t.jsxIdentifier("client"), t.jsxIdentifier("component-path")),
t.stringLiteral(meta.resolvedPath)
);
node.openingElement.attributes.push(componentPath);
}
if (!existingAttributes.find((attr) => attr === "client:component-export")) {
if (meta.name === "*") {
meta.name = getTagName(node).split(".").at(1);
}
const componentExport = t.jsxAttribute(
t.jsxNamespacedName(t.jsxIdentifier("client"), t.jsxIdentifier("component-export")),
t.stringLiteral(meta.name)
);
node.openingElement.attributes.push(componentExport);
}
if (!existingAttributes.find((attr) => attr === "client:component-hydration")) {
const staticMarker = t.jsxAttribute(
t.jsxNamespacedName(t.jsxIdentifier("client"), t.jsxIdentifier("component-hydration"))
);
node.openingElement.attributes.push(staticMarker);
}
}
function astroJSX() {
return {
visitor: {
Program: {
enter(path, state) {
if (!state.file.metadata.astro) {
state.file.metadata.astro = createDefaultAstroMetadata();
}
path.node.body.splice(
0,
0,
t.importDeclaration(
[t.importSpecifier(t.identifier("Fragment"), t.identifier("Fragment"))],
t.stringLiteral("astro/jsx-runtime")
)
);
}
},
ImportDeclaration(path, state) {
const source = path.node.source.value;
if (source.startsWith("astro/jsx-runtime")) return;
const specs = path.node.specifiers.map((spec) => {
if (t.isImportDefaultSpecifier(spec))
return { local: spec.local.name, imported: "default" };
if (t.isImportNamespaceSpecifier(spec)) return { local: spec.local.name, imported: "*" };
if (t.isIdentifier(spec.imported))
return { local: spec.local.name, imported: spec.imported.name };
return { local: spec.local.name, imported: spec.imported.value };
});
const imports = state.get("imports") ?? /* @__PURE__ */ new Map();
for (const spec of specs) {
if (imports.has(source)) {
const existing = imports.get(source);
existing.add(spec);
imports.set(source, existing);
} else {
imports.set(source, /* @__PURE__ */ new Set([spec]));
}
}
state.set("imports", imports);
},
JSXMemberExpression(path, state) {
const node = path.node;
if (state.filename?.endsWith(".mdx") && t.isJSXIdentifier(node.object) && node.object.name === "_components") {
return;
}
const parent = path.findParent((n) => t.isJSXElement(n.node));
const parentNode = parent.node;
const tagName = getTagName(parentNode);
if (!isComponent(tagName)) return;
if (!hasClientDirective(parentNode)) return;
const isClientOnly = isClientOnlyComponent(parentNode);
if (tagName === ClientOnlyPlaceholder) return;
const imports = state.get("imports") ?? /* @__PURE__ */ new Map();
const namespace = tagName.split(".");
for (const [source, specs] of imports) {
for (const { imported, local } of specs) {
const reference = path.referencesImport(source, imported);
if (reference) {
path.setData("import", { name: imported, path: source });
break;
}
if (namespace.at(0) === local) {
const name = imported === "*" ? imported : tagName;
path.setData("import", { name, path: source });
break;
}
}
}
const meta = path.getData("import");
if (meta) {
const resolvedPath = resolvePath(meta.path, state.filename);
if (isClientOnly) {
state.file.metadata.astro.clientOnlyComponents.push({
exportName: meta.name,
localName: "",
specifier: tagName,
resolvedPath
});
meta.resolvedPath = resolvedPath;
addClientOnlyMetadata(parentNode, meta);
} else {
state.file.metadata.astro.hydratedComponents.push({
exportName: "*",
localName: "",
specifier: tagName,
resolvedPath
});
meta.resolvedPath = resolvedPath;
addClientMetadata(parentNode, meta);
}
} else {
throw new Error(
`Unable to match <${getTagName(
parentNode
)}> with client:* directive to an import statement!`
);
}
},
JSXIdentifier(path, state) {
const isAttr = path.findParent((n) => t.isJSXAttribute(n.node));
if (isAttr) return;
const parent = path.findParent((n) => t.isJSXElement(n.node));
const parentNode = parent.node;
const tagName = getTagName(parentNode);
if (!isComponent(tagName)) return;
if (!hasClientDirective(parentNode)) return;
const isClientOnly = isClientOnlyComponent(parentNode);
if (tagName === ClientOnlyPlaceholder) return;
const imports = state.get("imports") ?? /* @__PURE__ */ new Map();
const namespace = tagName.split(".");
for (const [source, specs] of imports) {
for (const { imported, local } of specs) {
const reference = path.referencesImport(source, imported);
if (reference) {
path.setData("import", { name: imported, path: source });
break;
}
if (namespace.at(0) === local) {
path.setData("import", { name: imported, path: source });
break;
}
}
}
const meta = path.getData("import");
if (meta) {
if (meta.path.endsWith(".astro")) {
const displayName = getTagName(parentNode);
for (const attr of parentNode.openingElement.attributes) {
if (t.isJSXAttribute(attr)) {
const name = jsxAttributeToString(attr);
if (name.startsWith("client:")) {
console.warn(
`You are attempting to render <${displayName} ${name} />, but ${displayName} is an Astro component. Astro components do not render in the client and should not have a hydration directive. Please use a framework component for client rendering.`
);
}
}
}
}
const resolvedPath = resolvePath(meta.path, state.filename);
if (isClientOnly) {
state.file.metadata.astro.clientOnlyComponents.push({
exportName: meta.name,
localName: "",
specifier: meta.name,
resolvedPath
});
meta.resolvedPath = resolvedPath;
addClientOnlyMetadata(parentNode, meta);
} else {
state.file.metadata.astro.hydratedComponents.push({
exportName: meta.name,
localName: "",
specifier: meta.name,
resolvedPath
});
meta.resolvedPath = resolvedPath;
addClientMetadata(parentNode, meta);
}
} else {
throw new AstroError({
...AstroErrorData.NoMatchingImport,
message: AstroErrorData.NoMatchingImport.message(getTagName(parentNode))
});
}
}
}
};
}
export {
astroJSX as default
};

1
node_modules/astro/dist/jsx/component.d.ts generated vendored Normal file
View File

@@ -0,0 +1 @@
export declare function createAstroJSXComponent(factory: (...args: any[]) => any): (...args: any[]) => any;

10
node_modules/astro/dist/jsx/component.js generated vendored Normal file
View File

@@ -0,0 +1,10 @@
import { __astro_tag_component__ } from "../runtime/server/index.js";
import renderer from "./renderer.js";
const ASTRO_JSX_RENDERER_NAME = renderer.name;
function createAstroJSXComponent(factory) {
__astro_tag_component__(factory, ASTRO_JSX_RENDERER_NAME);
return factory;
}
export {
createAstroJSXComponent
};

2
node_modules/astro/dist/jsx/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,2 @@
export { createAstroJSXComponent } from './component.js';
export { default as renderer } from './renderer.js';

6
node_modules/astro/dist/jsx/index.js generated vendored Normal file
View File

@@ -0,0 +1,6 @@
import { createAstroJSXComponent } from "./component.js";
import { default as default2 } from "./renderer.js";
export {
createAstroJSXComponent,
default2 as renderer
};

5
node_modules/astro/dist/jsx/rehype.d.ts generated vendored Normal file
View File

@@ -0,0 +1,5 @@
import type { RehypePlugin } from '@astrojs/markdown-remark';
import type { VFile } from 'vfile';
import type { PluginMetadata } from '../vite-plugin-astro/types.js';
export declare const rehypeAnalyzeAstroMetadata: RehypePlugin;
export declare function getAstroMetadata(file: VFile): PluginMetadata["astro"] | undefined;

197
node_modules/astro/dist/jsx/rehype.js generated vendored Normal file
View File

@@ -0,0 +1,197 @@
import { visit } from "unist-util-visit";
import { AstroError } from "../core/errors/errors.js";
import { AstroErrorData } from "../core/errors/index.js";
import { resolvePath } from "../core/viteUtils.js";
import { createDefaultAstroMetadata } from "../vite-plugin-astro/metadata.js";
const ClientOnlyPlaceholder = "astro-client-only";
const rehypeAnalyzeAstroMetadata = () => {
return (tree, file) => {
const metadata = createDefaultAstroMetadata();
const imports = parseImports(tree.children);
visit(tree, (node) => {
if (node.type !== "mdxJsxFlowElement" && node.type !== "mdxJsxTextElement") return;
const tagName = node.name;
if (!tagName || !isComponent(tagName) || !hasClientDirective(node)) return;
const matchedImport = findMatchingImport(tagName, imports);
if (!matchedImport) {
throw new AstroError({
...AstroErrorData.NoMatchingImport,
message: AstroErrorData.NoMatchingImport.message(node.name)
});
}
if (matchedImport.path.endsWith(".astro")) {
const clientAttribute = node.attributes.find(
(attr) => attr.type === "mdxJsxAttribute" && attr.name.startsWith("client:")
);
if (clientAttribute) {
console.warn(
`You are attempting to render <${node.name} ${clientAttribute.name} />, but ${node.name} is an Astro component. Astro components do not render in the client and should not have a hydration directive. Please use a framework component for client rendering.`
);
}
}
const resolvedPath = resolvePath(matchedImport.path, file.path);
if (hasClientOnlyDirective(node)) {
metadata.clientOnlyComponents.push({
exportName: matchedImport.name,
localName: "",
specifier: tagName,
resolvedPath
});
addClientOnlyMetadata(node, matchedImport, resolvedPath);
} else {
metadata.hydratedComponents.push({
exportName: "*",
localName: "",
specifier: tagName,
resolvedPath
});
addClientMetadata(node, matchedImport, resolvedPath);
}
});
file.data.__astroMetadata = metadata;
};
};
function getAstroMetadata(file) {
return file.data.__astroMetadata;
}
function parseImports(children) {
const imports = /* @__PURE__ */ new Map();
for (const child of children) {
if (child.type !== "mdxjsEsm") continue;
const body = child.data?.estree?.body;
if (!body) continue;
for (const ast of body) {
if (ast.type !== "ImportDeclaration") continue;
const source = ast.source.value;
const specs = ast.specifiers.map((spec) => {
switch (spec.type) {
case "ImportDefaultSpecifier":
return { local: spec.local.name, imported: "default" };
case "ImportNamespaceSpecifier":
return { local: spec.local.name, imported: "*" };
case "ImportSpecifier": {
return {
local: spec.local.name,
imported: spec.imported.type === "Identifier" ? spec.imported.name : String(spec.imported.value)
};
}
default:
throw new Error("Unknown import declaration specifier: " + spec);
}
});
let specSet = imports.get(source);
if (!specSet) {
specSet = /* @__PURE__ */ new Set();
imports.set(source, specSet);
}
for (const spec of specs) {
specSet.add(spec);
}
}
}
return imports;
}
function isComponent(tagName) {
return tagName[0] && tagName[0].toLowerCase() !== tagName[0] || tagName.includes(".") || /[^a-zA-Z]/.test(tagName[0]);
}
function hasClientDirective(node) {
return node.attributes.some(
(attr) => attr.type === "mdxJsxAttribute" && attr.name.startsWith("client:")
);
}
function hasClientOnlyDirective(node) {
return node.attributes.some(
(attr) => attr.type === "mdxJsxAttribute" && attr.name === "client:only"
);
}
function findMatchingImport(tagName, imports) {
const tagSpecifier = tagName.split(".")[0];
for (const [source, specs] of imports) {
for (const { imported, local } of specs) {
if (local === tagSpecifier) {
if (tagSpecifier !== tagName) {
switch (imported) {
case "*": {
const accessPath = tagName.slice(tagSpecifier.length + 1);
return { name: accessPath, path: source };
}
case "default": {
const accessPath = tagName.slice(tagSpecifier.length + 1);
return { name: `default.${accessPath}`, path: source };
}
default: {
return { name: tagName, path: source };
}
}
}
return { name: imported, path: source };
}
}
}
}
function addClientMetadata(node, meta, resolvedPath) {
const attributeNames = node.attributes.map((attr) => attr.type === "mdxJsxAttribute" ? attr.name : null).filter(Boolean);
if (!attributeNames.includes("client:component-path")) {
node.attributes.push({
type: "mdxJsxAttribute",
name: "client:component-path",
value: resolvedPath
});
}
if (!attributeNames.includes("client:component-export")) {
if (meta.name === "*") {
meta.name = node.name.split(".").slice(1).join(".");
}
node.attributes.push({
type: "mdxJsxAttribute",
name: "client:component-export",
value: meta.name
});
}
if (!attributeNames.includes("client:component-hydration")) {
node.attributes.push({
type: "mdxJsxAttribute",
name: "client:component-hydration",
value: null
});
}
}
function addClientOnlyMetadata(node, meta, resolvedPath) {
const attributeNames = node.attributes.map((attr) => attr.type === "mdxJsxAttribute" ? attr.name : null).filter(Boolean);
if (!attributeNames.includes("client:display-name")) {
node.attributes.push({
type: "mdxJsxAttribute",
name: "client:display-name",
value: node.name
});
}
if (!attributeNames.includes("client:component-hydpathation")) {
node.attributes.push({
type: "mdxJsxAttribute",
name: "client:component-path",
value: resolvedPath
});
}
if (!attributeNames.includes("client:component-export")) {
if (meta.name === "*") {
meta.name = node.name.split(".").slice(1).join(".");
}
node.attributes.push({
type: "mdxJsxAttribute",
name: "client:component-export",
value: meta.name
});
}
if (!attributeNames.includes("client:component-hydration")) {
node.attributes.push({
type: "mdxJsxAttribute",
name: "client:component-hydration",
value: null
});
}
node.name = ClientOnlyPlaceholder;
}
export {
getAstroMetadata,
rehypeAnalyzeAstroMetadata
};

3
node_modules/astro/dist/jsx/renderer.d.ts generated vendored Normal file
View File

@@ -0,0 +1,3 @@
import type { AstroRenderer } from '../@types/astro.js';
declare const renderer: AstroRenderer;
export default renderer;

11
node_modules/astro/dist/jsx/renderer.js generated vendored Normal file
View File

@@ -0,0 +1,11 @@
import { jsxTransformOptions } from "./transform-options.js";
const renderer = {
name: "astro:jsx",
serverEntrypoint: "astro/jsx/server.js",
jsxImportSource: "astro",
jsxTransformOptions
};
var renderer_default = renderer;
export {
renderer_default as default
};

11
node_modules/astro/dist/jsx/server.d.ts generated vendored Normal file
View File

@@ -0,0 +1,11 @@
import type { NamedSSRLoadedRendererValue } from '../@types/astro.js';
export declare function check(Component: any, props: any, { default: children, ...slotted }?: {
default?: null | undefined;
}): Promise<any>;
export declare function renderToStaticMarkup(this: any, Component: any, props?: {}, { default: children, ...slotted }?: {
default?: null | undefined;
}): Promise<{
html: any;
}>;
declare const renderer: NamedSSRLoadedRendererValue;
export default renderer;

57
node_modules/astro/dist/jsx/server.js generated vendored Normal file
View File

@@ -0,0 +1,57 @@
import { AstroError, AstroUserError } from "../core/errors/errors.js";
import { AstroJSX, jsx } from "../jsx-runtime/index.js";
import { renderJSX } from "../runtime/server/jsx.js";
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, jsx(Component, { ...props, ...slots, children }));
return { html };
} catch (e) {
throwEnhancedErrorIfMdxComponent(e, Component);
throw e;
}
}
function throwEnhancedErrorIfMdxComponent(error, Component) {
if (Component[Symbol.for("mdx-component")]) {
if (AstroUserError.is(error)) return;
throw new AstroError({
message: error.message,
title: error.name,
hint: `This issue often occurs when your MDX component encounters runtime errors.`,
name: error.name,
stack: error.stack
});
}
}
const renderer = {
name: "astro:jsx",
check,
renderToStaticMarkup
};
var server_default = renderer;
export {
check,
server_default as default,
renderToStaticMarkup
};

5
node_modules/astro/dist/jsx/transform-options.d.ts generated vendored Normal file
View File

@@ -0,0 +1,5 @@
import type { JSXTransformConfig } from '../@types/astro.js';
/**
* @deprecated This function is no longer used. Remove in Astro 5.0
*/
export declare function jsxTransformOptions(): Promise<JSXTransformConfig>;

14
node_modules/astro/dist/jsx/transform-options.js generated vendored Normal file
View File

@@ -0,0 +1,14 @@
async function jsxTransformOptions() {
const plugin = await import("@babel/plugin-transform-react-jsx");
const jsx = plugin.default?.default ?? plugin.default;
const { default: astroJSX } = await import("./babel.js");
return {
plugins: [
astroJSX(),
jsx({}, { throwIfNamespace: false, runtime: "automatic", importSource: "astro" })
]
};
}
export {
jsxTransformOptions
};