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:
197
node_modules/astro/dist/jsx/rehype.js
generated
vendored
Normal file
197
node_modules/astro/dist/jsx/rehype.js
generated
vendored
Normal 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
|
||||
};
|
Reference in New Issue
Block a user