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

59
node_modules/@astrojs/markdown-remark/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,59 @@
MIT License
Copyright (c) 2021 Fred K. Schott
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"""
This license applies to parts of the `packages/create-astro` and `packages/astro` subdirectories originating from the https://github.com/sveltejs/kit repository:
Copyright (c) 2020 [these people](https://github.com/sveltejs/kit/graphs/contributors)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
"""
"""
This license applies to parts of the `packages/create-astro` and `packages/astro` subdirectories originating from the https://github.com/vitejs/vite repository:
MIT License
Copyright (c) 2019-present, Yuxi (Evan) You and Vite contributors
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"""

View File

@@ -0,0 +1,6 @@
import type { VFileData as Data, VFile } from 'vfile';
import type { MarkdownAstroData } from './types.js';
export declare class InvalidAstroDataError extends TypeError {
}
export declare function safelyGetAstroData(vfileData: Data): MarkdownAstroData | InvalidAstroDataError;
export declare function setVfileFrontmatter(vfile: VFile, frontmatter: Record<string, any>): void;

View File

@@ -0,0 +1,31 @@
function isValidAstroData(obj) {
if (typeof obj === "object" && obj !== null && obj.hasOwnProperty("frontmatter")) {
const { frontmatter } = obj;
try {
JSON.stringify(frontmatter);
} catch {
return false;
}
return typeof frontmatter === "object" && frontmatter !== null;
}
return false;
}
class InvalidAstroDataError extends TypeError {
}
function safelyGetAstroData(vfileData) {
const { astro } = vfileData;
if (!astro || !isValidAstroData(astro)) {
return new InvalidAstroDataError();
}
return astro;
}
function setVfileFrontmatter(vfile, frontmatter) {
vfile.data ??= {};
vfile.data.astro ??= {};
vfile.data.astro.frontmatter = frontmatter;
}
export {
InvalidAstroDataError,
safelyGetAstroData,
setVfileFrontmatter
};

View File

@@ -0,0 +1,15 @@
import type { Root } from 'hast';
type Highlighter = (code: string, language: string, options?: {
meta?: string;
}) => Promise<string>;
/**
* A hast utility to syntax highlight code blocks with a given syntax highlighter.
*
* @param tree
* The hast tree in which to syntax highlight code blocks.
* @param highlighter
* A function which receives the code and language, and returns the HTML of a syntax
* highlighted `<pre>` element.
*/
export declare function highlightCodeBlocks(tree: Root, highlighter: Highlighter): Promise<void>;
export {};

View File

@@ -0,0 +1,53 @@
import { fromHtml } from "hast-util-from-html";
import { toText } from "hast-util-to-text";
import { removePosition } from "unist-util-remove-position";
import { visitParents } from "unist-util-visit-parents";
const languagePattern = /\blanguage-(\S+)\b/;
async function highlightCodeBlocks(tree, highlighter) {
const nodes = [];
visitParents(tree, { type: "element", tagName: "code" }, (node, ancestors) => {
const parent = ancestors.at(-1);
if (parent?.type !== "element" || parent.tagName !== "pre") {
return;
}
if (parent.children.length !== 1) {
return;
}
let languageMatch;
let { className } = node.properties;
if (typeof className === "string") {
languageMatch = languagePattern.exec(className);
} else if (Array.isArray(className)) {
for (const cls of className) {
if (typeof cls !== "string") {
continue;
}
languageMatch = languagePattern.exec(cls);
if (languageMatch) {
break;
}
}
}
if (languageMatch?.[1] === "math") {
return;
}
nodes.push({
node,
language: languageMatch?.[1] || "plaintext",
parent,
grandParent: ancestors.at(-2)
});
});
for (const { node, language, grandParent, parent } of nodes) {
const meta = node.data?.meta ?? node.properties.metastring ?? void 0;
const code = toText(node, { whitespace: "pre" });
const html = await highlighter(code, language, { meta });
const replacement = fromHtml(html, { fragment: true }).children[0];
removePosition(replacement);
const index = grandParent.children.indexOf(parent);
grandParent.children[index] = replacement;
}
}
export {
highlightCodeBlocks
};

View File

@@ -0,0 +1,2 @@
import type * as unified from 'unified';
export declare function importPlugin(p: string): Promise<unified.Plugin>;

View File

@@ -0,0 +1,7 @@
async function importPlugin(p) {
const importResult = await import(p);
return importResult.default;
}
export {
importPlugin
};

View File

@@ -0,0 +1,2 @@
import type * as unified from 'unified';
export declare function importPlugin(p: string): Promise<unified.Plugin>;

View File

@@ -0,0 +1,18 @@
import path from "node:path";
import { pathToFileURL } from "node:url";
import { resolve as importMetaResolve } from "import-meta-resolve";
let cwdUrlStr;
async function importPlugin(p) {
try {
const importResult2 = await import(p);
return importResult2.default;
} catch {
}
cwdUrlStr ??= pathToFileURL(path.join(process.cwd(), "package.json")).toString();
const resolved = importMetaResolve(p, cwdUrlStr);
const importResult = await import(resolved);
return importResult.default;
}
export {
importPlugin
};

13
node_modules/@astrojs/markdown-remark/dist/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,13 @@
import type { AstroMarkdownOptions, MarkdownProcessor } from './types.js';
export { InvalidAstroDataError, setVfileFrontmatter } from './frontmatter-injection.js';
export { rehypeHeadingIds } from './rehype-collect-headings.js';
export { remarkCollectImages } from './remark-collect-images.js';
export { rehypePrism } from './rehype-prism.js';
export { rehypeShiki } from './rehype-shiki.js';
export { createShikiHighlighter, type ShikiHighlighter } from './shiki.js';
export * from './types.js';
export declare const markdownConfigDefaults: Required<AstroMarkdownOptions>;
/**
* Create a markdown preprocessor to render multiple markdown files
*/
export declare function createMarkdownProcessor(opts?: AstroMarkdownOptions): Promise<MarkdownProcessor>;

142
node_modules/@astrojs/markdown-remark/dist/index.js generated vendored Normal file
View File

@@ -0,0 +1,142 @@
import {
InvalidAstroDataError,
safelyGetAstroData,
setVfileFrontmatter
} from "./frontmatter-injection.js";
import { loadPlugins } from "./load-plugins.js";
import { rehypeHeadingIds } from "./rehype-collect-headings.js";
import { rehypePrism } from "./rehype-prism.js";
import { rehypeShiki } from "./rehype-shiki.js";
import { remarkCollectImages } from "./remark-collect-images.js";
import rehypeRaw from "rehype-raw";
import rehypeStringify from "rehype-stringify";
import remarkGfm from "remark-gfm";
import remarkParse from "remark-parse";
import remarkRehype from "remark-rehype";
import remarkSmartypants from "remark-smartypants";
import { unified } from "unified";
import { VFile } from "vfile";
import { rehypeImages } from "./rehype-images.js";
import { InvalidAstroDataError as InvalidAstroDataError2, setVfileFrontmatter as setVfileFrontmatter2 } from "./frontmatter-injection.js";
import { rehypeHeadingIds as rehypeHeadingIds2 } from "./rehype-collect-headings.js";
import { remarkCollectImages as remarkCollectImages2 } from "./remark-collect-images.js";
import { rehypePrism as rehypePrism2 } from "./rehype-prism.js";
import { rehypeShiki as rehypeShiki2 } from "./rehype-shiki.js";
import { createShikiHighlighter } from "./shiki.js";
export * from "./types.js";
const markdownConfigDefaults = {
syntaxHighlight: "shiki",
shikiConfig: {
langs: [],
theme: "github-dark",
themes: {},
wrap: false,
transformers: [],
langAlias: {}
},
remarkPlugins: [],
rehypePlugins: [],
remarkRehype: {},
gfm: true,
smartypants: true
};
const isPerformanceBenchmark = Boolean(process.env.ASTRO_PERFORMANCE_BENCHMARK);
async function createMarkdownProcessor(opts) {
const {
syntaxHighlight = markdownConfigDefaults.syntaxHighlight,
shikiConfig = markdownConfigDefaults.shikiConfig,
remarkPlugins = markdownConfigDefaults.remarkPlugins,
rehypePlugins = markdownConfigDefaults.rehypePlugins,
remarkRehype: remarkRehypeOptions = markdownConfigDefaults.remarkRehype,
gfm = markdownConfigDefaults.gfm,
smartypants = markdownConfigDefaults.smartypants
} = opts ?? {};
const loadedRemarkPlugins = await Promise.all(loadPlugins(remarkPlugins));
const loadedRehypePlugins = await Promise.all(loadPlugins(rehypePlugins));
const parser = unified().use(remarkParse);
if (!isPerformanceBenchmark) {
if (gfm) {
parser.use(remarkGfm);
}
if (smartypants) {
parser.use(remarkSmartypants);
}
}
for (const [plugin, pluginOpts] of loadedRemarkPlugins) {
parser.use(plugin, pluginOpts);
}
if (!isPerformanceBenchmark) {
parser.use(remarkCollectImages);
}
parser.use(remarkRehype, {
allowDangerousHtml: true,
passThrough: [],
...remarkRehypeOptions
});
if (!isPerformanceBenchmark) {
if (syntaxHighlight === "shiki") {
parser.use(rehypeShiki, shikiConfig);
} else if (syntaxHighlight === "prism") {
parser.use(rehypePrism);
}
}
for (const [plugin, pluginOpts] of loadedRehypePlugins) {
parser.use(plugin, pluginOpts);
}
parser.use(rehypeImages());
if (!isPerformanceBenchmark) {
parser.use(rehypeHeadingIds);
}
parser.use(rehypeRaw).use(rehypeStringify, { allowDangerousHtml: true });
return {
async render(content, renderOpts) {
const vfile = new VFile({ value: content, path: renderOpts?.fileURL });
setVfileFrontmatter(vfile, renderOpts?.frontmatter ?? {});
const result = await parser.process(vfile).catch((err) => {
err = prefixError(err, `Failed to parse Markdown file "${vfile.path}"`);
console.error(err);
throw err;
});
const astroData = safelyGetAstroData(result.data);
if (astroData instanceof InvalidAstroDataError) {
throw astroData;
}
return {
code: String(result.value),
metadata: {
headings: result.data.__astroHeadings ?? [],
imagePaths: result.data.imagePaths ?? /* @__PURE__ */ new Set(),
frontmatter: astroData.frontmatter ?? {}
}
};
}
};
}
function prefixError(err, prefix) {
if (err?.message) {
try {
err.message = `${prefix}:
${err.message}`;
return err;
} catch {
}
}
const wrappedError = new Error(`${prefix}${err ? `: ${err}` : ""}`);
try {
wrappedError.stack = err.stack;
wrappedError.cause = err;
} catch {
}
return wrappedError;
}
export {
InvalidAstroDataError2 as InvalidAstroDataError,
createMarkdownProcessor,
createShikiHighlighter,
markdownConfigDefaults,
rehypeHeadingIds2 as rehypeHeadingIds,
rehypePrism2 as rehypePrism,
rehypeShiki2 as rehypeShiki,
remarkCollectImages2 as remarkCollectImages,
setVfileFrontmatter2 as setVfileFrontmatter
};

View File

@@ -0,0 +1 @@
export { InvalidAstroDataError, safelyGetAstroData } from './frontmatter-injection.js';

View File

@@ -0,0 +1,5 @@
import { InvalidAstroDataError, safelyGetAstroData } from "./frontmatter-injection.js";
export {
InvalidAstroDataError,
safelyGetAstroData
};

View File

@@ -0,0 +1,2 @@
import type * as unified from 'unified';
export declare function loadPlugins(items: (string | [string, any] | unified.Plugin<any[], any> | [unified.Plugin<any[], any>, any])[]): Promise<[unified.Plugin, any?]>[];

View File

@@ -0,0 +1,22 @@
import { importPlugin as _importPlugin } from "#import-plugin";
async function importPlugin(p) {
if (typeof p === "string") {
return await _importPlugin(p);
} else {
return p;
}
}
function loadPlugins(items) {
return items.map((p) => {
return new Promise((resolve, reject) => {
if (Array.isArray(p)) {
const [plugin, opts] = p;
return importPlugin(plugin).then((m) => resolve([m, opts])).catch((e) => reject(e));
}
return importPlugin(p).then((m) => resolve([m])).catch((e) => reject(e));
});
});
}
export {
loadPlugins
};

View File

@@ -0,0 +1,2 @@
import type { RehypePlugin } from './types.js';
export declare function rehypeHeadingIds(): ReturnType<RehypePlugin>;

View File

@@ -0,0 +1,90 @@
import Slugger from "github-slugger";
import { visit } from "unist-util-visit";
import { InvalidAstroDataError, safelyGetAstroData } from "./frontmatter-injection.js";
const rawNodeTypes = /* @__PURE__ */ new Set(["text", "raw", "mdxTextExpression"]);
const codeTagNames = /* @__PURE__ */ new Set(["code", "pre"]);
function rehypeHeadingIds() {
return function(tree, file) {
const headings = [];
const slugger = new Slugger();
const isMDX = isMDXFile(file);
const astroData = safelyGetAstroData(file.data);
visit(tree, (node) => {
if (node.type !== "element") return;
const { tagName } = node;
if (tagName[0] !== "h") return;
const [, level] = /h([0-6])/.exec(tagName) ?? [];
if (!level) return;
const depth = Number.parseInt(level);
let text = "";
visit(node, (child, __, parent) => {
if (child.type === "element" || parent == null) {
return;
}
if (child.type === "raw") {
if (/^\n?<.*>\n?$/.test(child.value)) {
return;
}
}
if (rawNodeTypes.has(child.type)) {
if (isMDX || codeTagNames.has(parent.tagName)) {
let value = child.value;
if (isMdxTextExpression(child) && !(astroData instanceof InvalidAstroDataError)) {
const frontmatterPath = getMdxFrontmatterVariablePath(child);
if (Array.isArray(frontmatterPath) && frontmatterPath.length > 0) {
const frontmatterValue = getMdxFrontmatterVariableValue(astroData, frontmatterPath);
if (typeof frontmatterValue === "string") {
value = frontmatterValue;
}
}
}
text += value;
} else {
text += child.value.replace(/\{/g, "${");
}
}
});
node.properties = node.properties || {};
if (typeof node.properties.id !== "string") {
let slug = slugger.slug(text);
if (slug.endsWith("-")) slug = slug.slice(0, -1);
node.properties.id = slug;
}
headings.push({ depth, slug: node.properties.id, text });
});
file.data.__astroHeadings = headings;
};
}
function isMDXFile(file) {
return Boolean(file.history[0]?.endsWith(".mdx"));
}
function getMdxFrontmatterVariablePath(node) {
if (!node.data?.estree || node.data.estree.body.length !== 1) return new Error();
const statement = node.data.estree.body[0];
if (statement?.type !== "ExpressionStatement" || statement.expression.type !== "MemberExpression")
return new Error();
let expression = statement.expression;
const expressionPath = [];
while (expression.type === "MemberExpression" && expression.property.type === (expression.computed ? "Literal" : "Identifier")) {
expressionPath.push(
expression.property.type === "Literal" ? String(expression.property.value) : expression.property.name
);
expression = expression.object;
}
if (expression.type !== "Identifier" || expression.name !== "frontmatter") return new Error();
return expressionPath.reverse();
}
function getMdxFrontmatterVariableValue(astroData, path) {
let value = astroData.frontmatter;
for (const key of path) {
if (!value[key]) return void 0;
value = value[key];
}
return value;
}
function isMdxTextExpression(node) {
return node.type === "mdxTextExpression";
}
export {
rehypeHeadingIds
};

View File

@@ -0,0 +1,2 @@
import type { MarkdownVFile } from './types.js';
export declare function rehypeImages(): () => (tree: any, file: MarkdownVFile) => void;

View File

@@ -0,0 +1,25 @@
import { visit } from "unist-util-visit";
function rehypeImages() {
return () => function(tree, file) {
const imageOccurrenceMap = /* @__PURE__ */ new Map();
visit(tree, (node) => {
if (node.type !== "element") return;
if (node.tagName !== "img") return;
if (node.properties?.src) {
node.properties.src = decodeURI(node.properties.src);
if (file.data.imagePaths?.has(node.properties.src)) {
const { ...props } = node.properties;
const index = imageOccurrenceMap.get(node.properties.src) || 0;
imageOccurrenceMap.set(node.properties.src, index + 1);
node.properties["__ASTRO_IMAGE_"] = JSON.stringify({ ...props, index });
Object.keys(props).forEach((prop) => {
delete node.properties[prop];
});
}
}
});
};
}
export {
rehypeImages
};

View File

@@ -0,0 +1,3 @@
import type { Root } from 'hast';
import type { Plugin } from 'unified';
export declare const rehypePrism: Plugin<[], Root>;

View File

@@ -0,0 +1,15 @@
import { runHighlighterWithAstro } from "@astrojs/prism/dist/highlighter";
import { highlightCodeBlocks } from "./highlight.js";
const rehypePrism = () => {
return async (tree) => {
await highlightCodeBlocks(tree, (code, language) => {
let { html, classLanguage } = runHighlighterWithAstro(language, code);
return Promise.resolve(
`<pre class="${classLanguage}" data-language="${language}"><code is:raw class="${classLanguage}">${html}</code></pre>`
);
});
};
};
export {
rehypePrism
};

View File

@@ -0,0 +1,4 @@
import type { Root } from 'hast';
import type { Plugin } from 'unified';
import type { ShikiConfig } from './types.js';
export declare const rehypeShiki: Plugin<[ShikiConfig?], Root>;

View File

@@ -0,0 +1,13 @@
import { highlightCodeBlocks } from "./highlight.js";
import { createShikiHighlighter } from "./shiki.js";
const rehypeShiki = (config) => {
let highlighterAsync;
return async (tree) => {
highlighterAsync ??= createShikiHighlighter(config);
const highlighter = await highlighterAsync;
await highlightCodeBlocks(tree, highlighter.highlight);
};
};
export {
rehypeShiki
};

View File

@@ -0,0 +1,2 @@
import type { MarkdownVFile } from './types.js';
export declare function remarkCollectImages(): (tree: any, vfile: MarkdownVFile) => void;

View File

@@ -0,0 +1,36 @@
import { definitions } from "mdast-util-definitions";
import { visit } from "unist-util-visit";
function remarkCollectImages() {
return function(tree, vfile) {
if (typeof vfile?.path !== "string") return;
const definition = definitions(tree);
const imagePaths = /* @__PURE__ */ new Set();
visit(tree, ["image", "imageReference"], (node) => {
if (node.type === "image") {
if (shouldOptimizeImage(node.url)) imagePaths.add(decodeURI(node.url));
}
if (node.type === "imageReference") {
const imageDefinition = definition(node.identifier);
if (imageDefinition) {
if (shouldOptimizeImage(imageDefinition.url))
imagePaths.add(decodeURI(imageDefinition.url));
}
}
});
vfile.data.imagePaths = imagePaths;
};
}
function shouldOptimizeImage(src) {
return !isValidUrl(src) && !src.startsWith("/");
}
function isValidUrl(str) {
try {
new URL(str);
return true;
} catch {
return false;
}
}
export {
remarkCollectImages
};

12
node_modules/@astrojs/markdown-remark/dist/shiki.d.ts generated vendored Normal file
View File

@@ -0,0 +1,12 @@
import type { ShikiConfig } from './types.js';
export interface ShikiHighlighter {
highlight(code: string, lang?: string, options?: {
inline?: boolean;
attributes?: Record<string, string>;
/**
* Raw `meta` information to be used by Shiki transformers
*/
meta?: string;
}): Promise<string>;
}
export declare function createShikiHighlighter({ langs, theme, themes, defaultColor, wrap, transformers, langAlias, }?: ShikiConfig): Promise<ShikiHighlighter>;

130
node_modules/@astrojs/markdown-remark/dist/shiki.js generated vendored Normal file
View File

@@ -0,0 +1,130 @@
import {
createCssVariablesTheme,
getHighlighter,
isSpecialLang
} from "shiki";
import { visit } from "unist-util-visit";
const ASTRO_COLOR_REPLACEMENTS = {
"--astro-code-foreground": "--astro-code-color-text",
"--astro-code-background": "--astro-code-color-background"
};
const COLOR_REPLACEMENT_REGEX = new RegExp(
`${Object.keys(ASTRO_COLOR_REPLACEMENTS).join("|")}`,
"g"
);
let _cssVariablesTheme;
const cssVariablesTheme = () => _cssVariablesTheme ?? (_cssVariablesTheme = createCssVariablesTheme({ variablePrefix: "--astro-code-" }));
async function createShikiHighlighter({
langs = [],
theme = "github-dark",
themes = {},
defaultColor,
wrap = false,
transformers = [],
langAlias = {}
} = {}) {
theme = theme === "css-variables" ? cssVariablesTheme() : theme;
const highlighter = await getHighlighter({
langs: ["plaintext", ...langs],
langAlias,
themes: Object.values(themes).length ? Object.values(themes) : [theme]
});
return {
async highlight(code, lang = "plaintext", options) {
const resolvedLang = langAlias[lang] ?? lang;
const loadedLanguages = highlighter.getLoadedLanguages();
if (!isSpecialLang(lang) && !loadedLanguages.includes(resolvedLang)) {
try {
await highlighter.loadLanguage(resolvedLang);
} catch (_err) {
const langStr = lang === resolvedLang ? `"${lang}"` : `"${lang}" (aliased to "${resolvedLang}")`;
console.warn(
`[Shiki] The language ${langStr} doesn't exist, falling back to "plaintext".`
);
lang = "plaintext";
}
}
const themeOptions = Object.values(themes).length ? { themes } : { theme };
const inline = options?.inline ?? false;
return highlighter.codeToHtml(code, {
...themeOptions,
defaultColor,
lang,
// NOTE: while we can spread `options.attributes` here so that Shiki can auto-serialize this as rendered
// attributes on the top-level tag, it's not clear whether it is fine to pass all attributes as meta, as
// they're technically not meta, nor parsed from Shiki's `parseMetaString` API.
meta: options?.meta ? { __raw: options?.meta } : void 0,
transformers: [
{
pre(node) {
if (inline) {
node.tagName = "code";
}
const {
class: attributesClass,
style: attributesStyle,
...rest
} = options?.attributes ?? {};
Object.assign(node.properties, rest);
const classValue = (normalizePropAsString(node.properties.class) ?? "") + (attributesClass ? ` ${attributesClass}` : "");
const styleValue = (normalizePropAsString(node.properties.style) ?? "") + (attributesStyle ? `; ${attributesStyle}` : "");
node.properties.class = classValue.replace(/shiki/g, "astro-code");
node.properties.dataLanguage = lang;
if (wrap === false) {
node.properties.style = styleValue + "; overflow-x: auto;";
} else if (wrap === true) {
node.properties.style = styleValue + "; overflow-x: auto; white-space: pre-wrap; word-wrap: break-word;";
}
},
line(node) {
if (resolvedLang === "diff") {
const innerSpanNode = node.children[0];
const innerSpanTextNode = innerSpanNode?.type === "element" && innerSpanNode.children?.[0];
if (innerSpanTextNode && innerSpanTextNode.type === "text") {
const start = innerSpanTextNode.value[0];
if (start === "+" || start === "-") {
innerSpanTextNode.value = innerSpanTextNode.value.slice(1);
innerSpanNode.children.unshift({
type: "element",
tagName: "span",
properties: { style: "user-select: none;" },
children: [{ type: "text", value: start }]
});
}
}
}
},
code(node) {
if (inline) {
return node.children[0];
}
},
root(node) {
if (Object.values(themes).length) {
return;
}
const themeName = typeof theme === "string" ? theme : theme.name;
if (themeName === "css-variables") {
visit(node, "element", (child) => {
if (child.properties?.style) {
child.properties.style = replaceCssVariables(child.properties.style);
}
});
}
}
},
...transformers
]
});
}
};
}
function normalizePropAsString(value) {
return Array.isArray(value) ? value.join(" ") : value;
}
function replaceCssVariables(str) {
return str.replace(COLOR_REPLACEMENT_REGEX, (match) => ASTRO_COLOR_REPLACEMENTS[match] || match);
}
export {
createShikiHighlighter
};

60
node_modules/@astrojs/markdown-remark/dist/types.d.ts generated vendored Normal file
View File

@@ -0,0 +1,60 @@
import type * as hast from 'hast';
import type * as mdast from 'mdast';
import type { Options as RemarkRehypeOptions } from 'remark-rehype';
import type { BuiltinTheme, HighlighterCoreOptions, LanguageRegistration, ShikiTransformer, ThemeRegistration, ThemeRegistrationRaw } from 'shiki';
import type * as unified from 'unified';
import type { DataMap, VFile } from 'vfile';
export type { Node } from 'unist';
export type MarkdownAstroData = {
frontmatter: Record<string, any>;
};
export type RemarkPlugin<PluginParameters extends any[] = any[]> = unified.Plugin<PluginParameters, mdast.Root>;
export type RemarkPlugins = (string | [string, any] | RemarkPlugin | [RemarkPlugin, any])[];
export type RehypePlugin<PluginParameters extends any[] = any[]> = unified.Plugin<PluginParameters, hast.Root>;
export type RehypePlugins = (string | [string, any] | RehypePlugin | [RehypePlugin, any])[];
export type RemarkRehype = RemarkRehypeOptions;
export type ThemePresets = BuiltinTheme | 'css-variables';
export interface ShikiConfig {
langs?: LanguageRegistration[];
langAlias?: HighlighterCoreOptions['langAlias'];
theme?: ThemePresets | ThemeRegistration | ThemeRegistrationRaw;
themes?: Record<string, ThemePresets | ThemeRegistration | ThemeRegistrationRaw>;
defaultColor?: 'light' | 'dark' | string | false;
wrap?: boolean | null;
transformers?: ShikiTransformer[];
}
export interface AstroMarkdownOptions {
syntaxHighlight?: 'shiki' | 'prism' | false;
shikiConfig?: ShikiConfig;
remarkPlugins?: RemarkPlugins;
rehypePlugins?: RehypePlugins;
remarkRehype?: RemarkRehype;
gfm?: boolean;
smartypants?: boolean;
}
export interface MarkdownProcessor {
render: (content: string, opts?: MarkdownProcessorRenderOptions) => Promise<MarkdownProcessorRenderResult>;
}
export interface MarkdownProcessorRenderOptions {
/** Used for frontmatter injection plugins */
frontmatter?: Record<string, any>;
}
export interface MarkdownProcessorRenderResult {
code: string;
metadata: {
headings: MarkdownHeading[];
imagePaths: Set<string>;
frontmatter: Record<string, any>;
};
}
export interface MarkdownHeading {
depth: number;
slug: string;
text: string;
}
export interface MarkdownVFile extends VFile {
data: Record<string, unknown> & Partial<DataMap> & {
__astroHeadings?: MarkdownHeading[];
imagePaths?: Set<string>;
};
}

0
node_modules/@astrojs/markdown-remark/dist/types.js generated vendored Normal file
View File

67
node_modules/@astrojs/markdown-remark/package.json generated vendored Normal file
View File

@@ -0,0 +1,67 @@
{
"name": "@astrojs/markdown-remark",
"version": "5.3.0",
"type": "module",
"author": "withastro",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/withastro/astro.git",
"directory": "packages/markdown/remark"
},
"bugs": "https://github.com/withastro/astro/issues",
"homepage": "https://astro.build",
"main": "./dist/index.js",
"exports": {
".": "./dist/index.js",
"./dist/internal.js": "./dist/internal.js"
},
"imports": {
"#import-plugin": {
"browser": "./dist/import-plugin-browser.js",
"default": "./dist/import-plugin-default.js"
}
},
"files": [
"dist"
],
"dependencies": {
"github-slugger": "^2.0.0",
"hast-util-from-html": "^2.0.3",
"hast-util-to-text": "^4.0.2",
"import-meta-resolve": "^4.1.0",
"mdast-util-definitions": "^6.0.0",
"rehype-raw": "^7.0.0",
"rehype-stringify": "^10.0.1",
"remark-gfm": "^4.0.0",
"remark-parse": "^11.0.0",
"remark-rehype": "^11.1.1",
"remark-smartypants": "^3.0.2",
"shiki": "^1.22.0",
"unified": "^11.0.5",
"unist-util-remove-position": "^5.0.0",
"unist-util-visit": "^5.0.0",
"unist-util-visit-parents": "^6.0.1",
"vfile": "^6.0.3",
"@astrojs/prism": "3.1.0"
},
"devDependencies": {
"@types/estree": "^1.0.6",
"@types/hast": "^3.0.4",
"@types/mdast": "^4.0.4",
"@types/unist": "^3.0.3",
"esbuild": "^0.21.5",
"mdast-util-mdx-expression": "^2.0.1",
"astro-scripts": "0.0.14"
},
"publishConfig": {
"provenance": true
},
"scripts": {
"prepublish": "pnpm build",
"build": "astro-scripts build \"src/**/*.ts\" && tsc -p tsconfig.json",
"build:ci": "astro-scripts build \"src/**/*.ts\"",
"dev": "astro-scripts dev \"src/**/*.ts\"",
"test": "astro-scripts test \"test/**/*.test.js\""
}
}