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

View File

@@ -0,0 +1,2 @@
import type { ContentEntryType } from '../@types/astro.js';
export declare const markdownContentEntryType: ContentEntryType;

View File

@@ -0,0 +1,42 @@
import { fileURLToPath, pathToFileURL } from "node:url";
import { createMarkdownProcessor } from "@astrojs/markdown-remark";
import { safeParseFrontmatter } from "../content/utils.js";
const markdownContentEntryType = {
extensions: [".md"],
async getEntryInfo({ contents, fileUrl }) {
const parsed = safeParseFrontmatter(contents, fileURLToPath(fileUrl));
return {
data: parsed.data,
body: parsed.content,
slug: parsed.data.slug,
rawData: parsed.matter
};
},
// We need to handle propagation for Markdown because they support layouts which will bring in styles.
handlePropagation: true,
async getRenderFunction(config) {
const processor = await createMarkdownProcessor(config.markdown);
return async function renderToString(entry) {
if (!entry.body) {
return {
html: ""
};
}
const result = await processor.render(entry.body, {
frontmatter: entry.data,
// @ts-expect-error Internal API
fileURL: entry.filePath ? pathToFileURL(entry.filePath) : void 0
});
return {
html: result.code,
metadata: {
...result.metadata,
imagePaths: Array.from(result.metadata.imagePaths)
}
};
};
}
};
export {
markdownContentEntryType
};

View File

@@ -0,0 +1,5 @@
export type MarkdownImagePath = {
raw: string;
safeName: string;
};
export declare function getMarkdownCodeForImages(imagePaths: MarkdownImagePath[], html: string): string;

61
node_modules/astro/dist/vite-plugin-markdown/images.js generated vendored Normal file
View File

@@ -0,0 +1,61 @@
function getMarkdownCodeForImages(imagePaths, html) {
return `
import { getImage } from "astro:assets";
${imagePaths.map((entry) => `import Astro__${entry.safeName} from ${JSON.stringify(entry.raw)};`).join("\n")}
const images = async function(html) {
const imageSources = {};
${imagePaths.map((entry) => {
const rawUrl = JSON.stringify(entry.raw);
return `{
const regex = new RegExp('__ASTRO_IMAGE_="([^"]*' + ${rawUrl.replace(
/[.*+?^${}()|[\]\\]/g,
"\\\\$&"
)} + '[^"]*)"', 'g');
let match;
let occurrenceCounter = 0;
while ((match = regex.exec(html)) !== null) {
const matchKey = ${rawUrl} + '_' + occurrenceCounter;
const imageProps = JSON.parse(match[1].replace(/"/g, '"'));
const { src, ...props } = imageProps;
imageSources[matchKey] = await getImage({src: Astro__${entry.safeName}, ...props});
occurrenceCounter++;
}
}`;
}).join("\n")}
return imageSources;
};
async function updateImageReferences(html) {
return images(html).then((imageSources) => {
return html.replaceAll(/__ASTRO_IMAGE_="([^"]+)"/gm, (full, imagePath) => {
const decodedImagePath = JSON.parse(imagePath.replace(/"/g, '"'));
// Use the 'index' property for each image occurrence
const srcKey = decodedImagePath.src + '_' + decodedImagePath.index;
if (imageSources[srcKey].srcSet && imageSources[srcKey].srcSet.values.length > 0) {
imageSources[srcKey].attributes.srcset = imageSources[srcKey].srcSet.attribute;
}
const { index, ...attributesWithoutIndex } = imageSources[srcKey].attributes;
return spreadAttributes({
src: imageSources[srcKey].src,
...attributesWithoutIndex,
});
});
});
}
// NOTE: This causes a top-level await to appear in the user's code, which can break very easily due to a Rollup
// bug and certain adapters not supporting it correctly. See: https://github.com/rollup/rollup/issues/4708
// Tread carefully!
const html = await updateImageReferences(${JSON.stringify(html)});
`;
}
export {
getMarkdownCodeForImages
};

View File

@@ -0,0 +1,9 @@
import type { Plugin } from 'vite';
import type { AstroSettings } from '../@types/astro.js';
import type { Logger } from '../core/logger/core.js';
interface AstroPluginOptions {
settings: AstroSettings;
logger: Logger;
}
export default function markdown({ settings, logger }: AstroPluginOptions): Plugin;
export {};

133
node_modules/astro/dist/vite-plugin-markdown/index.js generated vendored Normal file
View File

@@ -0,0 +1,133 @@
import fs from "node:fs";
import { fileURLToPath, pathToFileURL } from "node:url";
import {
InvalidAstroDataError,
createMarkdownProcessor
} from "@astrojs/markdown-remark";
import { normalizePath } from "vite";
import { safeParseFrontmatter } from "../content/utils.js";
import { AstroError, AstroErrorData } from "../core/errors/index.js";
import { isMarkdownFile } from "../core/util.js";
import { shorthash } from "../runtime/server/shorthash.js";
import { createDefaultAstroMetadata } from "../vite-plugin-astro/metadata.js";
import { getFileInfo } from "../vite-plugin-utils/index.js";
import { getMarkdownCodeForImages } from "./images.js";
const astroServerRuntimeModulePath = normalizePath(
fileURLToPath(new URL("../runtime/server/index.js", import.meta.url))
);
const astroErrorModulePath = normalizePath(
fileURLToPath(new URL("../core/errors/index.js", import.meta.url))
);
function markdown({ settings, logger }) {
let processor;
return {
enforce: "pre",
name: "astro:markdown",
buildEnd() {
processor = void 0;
},
async resolveId(source, importer, options) {
if (importer?.endsWith(".md") && source[0] !== "/") {
let resolved = await this.resolve(source, importer, options);
if (!resolved) resolved = await this.resolve("./" + source, importer, options);
return resolved;
}
},
// Why not the "transform" hook instead of "load" + readFile?
// A: Vite transforms all "import.meta.env" references to their values before
// passing to the transform hook. This lets us get the truly raw value
// to escape "import.meta.env" ourselves.
async load(id) {
if (isMarkdownFile(id)) {
const { fileId, fileUrl } = getFileInfo(id, settings.config);
const rawFile = await fs.promises.readFile(fileId, "utf-8");
const raw = safeParseFrontmatter(rawFile, id);
const fileURL = pathToFileURL(fileId);
if (!processor) {
processor = createMarkdownProcessor(settings.config.markdown);
}
const renderResult = await (await processor).render(raw.content, {
// @ts-expect-error passing internal prop
fileURL,
frontmatter: raw.data
}).catch((err) => {
if (err instanceof InvalidAstroDataError) {
throw new AstroError(AstroErrorData.InvalidFrontmatterInjectionError);
}
throw err;
});
let html = renderResult.code;
const { headings, imagePaths: rawImagePaths, frontmatter } = renderResult.metadata;
const imagePaths = [];
for (const imagePath of rawImagePaths.values()) {
imagePaths.push({
raw: imagePath,
safeName: shorthash(imagePath)
});
}
const { layout } = frontmatter;
if (frontmatter.setup) {
logger.warn(
"markdown",
`[${id}] Astro now supports MDX! Support for components in ".md" (or alternative extensions like ".markdown") files using the "setup" frontmatter is no longer enabled by default. Migrate this file to MDX.`
);
}
const code = `
import { unescapeHTML, spreadAttributes, createComponent, render, renderComponent, maybeRenderHead } from ${JSON.stringify(
astroServerRuntimeModulePath
)};
import { AstroError, AstroErrorData } from ${JSON.stringify(astroErrorModulePath)};
${layout ? `import Layout from ${JSON.stringify(layout)};` : ""}
${// Only include the code relevant to `astro:assets` if there's images in the file
imagePaths.length > 0 ? getMarkdownCodeForImages(imagePaths, html) : `const html = ${JSON.stringify(html)};`}
export const frontmatter = ${JSON.stringify(frontmatter)};
export const file = ${JSON.stringify(fileId)};
export const url = ${JSON.stringify(fileUrl)};
export function rawContent() {
return ${JSON.stringify(raw.content)};
}
export function compiledContent() {
return html;
}
export function getHeadings() {
return ${JSON.stringify(headings)};
}
export const Content = createComponent((result, _props, slots) => {
const { layout, ...content } = frontmatter;
content.file = file;
content.url = url;
return ${layout ? `render\`\${renderComponent(result, 'Layout', Layout, {
file,
url,
content,
frontmatter: content,
headings: getHeadings(),
rawContent,
compiledContent,
'server:root': true,
}, {
'default': () => render\`\${unescapeHTML(html)}\`
})}\`;` : `render\`\${maybeRenderHead(result)}\${unescapeHTML(html)}\`;`}
});
export default Content;
`;
return {
code,
meta: {
astro: createDefaultAstroMetadata(),
vite: {
lang: "ts"
}
}
};
}
}
};
}
export {
markdown as default
};