All files config.js

97.67% Statements 42/43
75.75% Branches 25/33
85.71% Functions 6/7
100% Lines 40/40

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90          1x   7x   1x 3x 3x 1x   2x 1x   1x     1x 2x 2x 1x   1x 1x     1x   1x 5x 8x 8x 4x 4x   4x 4x     5x                               1x 2x 1x     1x 1x 4x 4x 1x     3x 3x 3x 3x                   1x 1x     1x    
import fs from "node:fs";
import path from "node:path";
import { fileURLToPath } from "node:url";
 
/** Absolute package root for Vite's local-link filesystem allowlist. */
export const arraiThemeRoot = fileURLToPath(new URL("..", import.meta.url));
 
const toPosixPath = (value) => value.split(path.sep).join("/");
 
const routeFromRelativePath = (relativePath) => {
    const normalized = toPosixPath(relativePath);
    if (normalized === "index.md") {
        return "/";
    }
    if (normalized.endsWith("/index.md")) {
        return `/${normalized.slice(0, -"index.md".length)}`.replace(/\/$/, "") || "/";
    }
    return `/${normalized.replace(/\.md$/, "")}`;
};
 
const frontmatterTitle = (source) => {
    const frontmatter = source.match(/^---\r?\n([\s\S]*?)\r?\n---/);
    if (!frontmatter) {
        return null;
    }
    const title = frontmatter[1].match(/^title:\s*["']?(.+?)["']?\s*$/m);
    return title?.[1] || null;
};
 
const headingTitle = (source) => source.match(/^#\s+(.+?)\s*$/m)?.[1] || null;
 
const walkMarkdown = (directory, found = []) => {
    for (const entry of fs.readdirSync(directory, { withFileTypes: true })) {
        const absolutePath = path.join(directory, entry.name);
        if (entry.isDirectory()) {
            Eif (entry.name !== ".vitepress" && entry.name !== "node_modules") {
                walkMarkdown(absolutePath, found);
            }
        } else Eif (entry.name.endsWith(".md")) {
            found.push(absolutePath);
        }
    }
    return found;
};
 
/**
 * Index Markdown pages for breadcrumb labels and safe links.
 *
 * Virtual routes can label structural segments that have no page. They are
 * non-linking by default, which prevents breadcrumb links to missing indexes.
 *
 * @param {object} options - Index options.
 * @param {string} options.docsRoot - Absolute VitePress source directory.
 * @param {(relativePath: string) => boolean} [options.exclude] - Page exclusion predicate.
 * @param {(page: object) => string | null} [options.getTitle] - Custom page-title resolver.
 * @param {object} [options.virtualRoutes] - Additional structural route labels.
 * @returns {object} Route metadata for `themeConfig.breadcrumbs.routes`.
 */
export const buildBreadcrumbRoutes = ({ docsRoot, exclude = () => false, getTitle, virtualRoutes = {} }) => {
    if (!path.isAbsolute(docsRoot)) {
        throw new TypeError("docsRoot must be an absolute path.");
    }
 
    const routes = {};
    for (const filePath of walkMarkdown(docsRoot)) {
        const relativePath = toPosixPath(path.relative(docsRoot, filePath));
        if (exclude(relativePath)) {
            continue;
        }
 
        const source = fs.readFileSync(filePath, "utf8");
        const route = routeFromRelativePath(relativePath);
        const fallback = path.basename(filePath, ".md");
        routes[route] = {
            text:
                getTitle?.({ filePath, relativePath, route, source }) ||
                frontmatterTitle(source) ||
                headingTitle(source) ||
                fallback,
            link: true,
        };
    }
 
    for (const [route, entry] of Object.entries(virtualRoutes)) {
        routes[route] = typeof entry === "string" ? { text: entry, link: false } : { link: false, ...entry };
    }
 
    return routes;
};