/**
 * Filesystem loader for `docs/product/<slug>/index.{md,mdx}` (Path W).
 *
 * Used by the install runtime via `src/services/docs_install/loader.ts` to
 * read from the bundled `dist/docs-bundled/` mirror, and by tests to load
 * directly from the repo's `docs/product/`. The SPA does NOT use this module
 * — Vite's `import.meta.glob('/docs/product/**.md', { query: '?raw' })`
 * inlines the files at build time.
 */
import { readFileSync, readdirSync, statSync, existsSync } from "node:fs";
import path from "node:path";
import { parseFrontmatter } from "./frontmatter.js";
const FILE_NAMES_BY_EXT = [
    { name: "index.md", ext: "md" },
    { name: "index.mdx", ext: "mdx" },
];
function findIndexFile(slugDir) {
    for (const candidate of FILE_NAMES_BY_EXT) {
        const abs = path.join(slugDir, candidate.name);
        if (existsSync(abs))
            return { absPath: abs, ext: candidate.ext };
    }
    return null;
}
function isSlugDirectory(name) {
    if (!name || name.startsWith(".") || name.startsWith("_"))
        return false;
    return /^[a-z][a-z0-9-]*$/.test(name);
}
/**
 * Discover all bundled doc slugs under `rootDir` (one subdirectory per slug).
 *
 * @param rootDir Absolute path to the bundled docs root, e.g.
 *   `/path/to/docs/product` (dev) or `/path/to/dist/docs-bundled` (prod).
 */
export function listDocSlugs(rootDir) {
    if (!existsSync(rootDir))
        return [];
    const entries = readdirSync(rootDir, { withFileTypes: true });
    const slugs = [];
    for (const entry of entries) {
        if (!entry.isDirectory())
            continue;
        if (!isSlugDirectory(entry.name))
            continue;
        const slugDir = path.join(rootDir, entry.name);
        if (!findIndexFile(slugDir))
            continue;
        slugs.push(entry.name);
    }
    slugs.sort();
    return slugs;
}
/**
 * Load and validate a single doc source by slug. Throws if the slug is
 * unknown or the front-matter is malformed.
 */
export function loadDocSource(rootDir, slug) {
    if (!isSlugDirectory(slug)) {
        throw new Error(`invalid doc slug: ${JSON.stringify(slug)}`);
    }
    const slugDir = path.join(rootDir, slug);
    const stat = existsSync(slugDir) ? statSync(slugDir) : null;
    if (!stat || !stat.isDirectory()) {
        throw new Error(`doc slug not found: ${slug} (looked in ${rootDir})`);
    }
    const indexFile = findIndexFile(slugDir);
    if (!indexFile) {
        throw new Error(`doc slug ${slug} has no index.md or index.mdx`);
    }
    const raw = readFileSync(indexFile.absPath, "utf-8");
    const { frontmatter, body } = parseFrontmatter(raw, indexFile.absPath);
    if (frontmatter.slug !== slug) {
        throw new Error(`frontmatter.slug (${frontmatter.slug}) does not match directory name (${slug}) at ${indexFile.absPath}`);
    }
    return {
        slug,
        extension: indexFile.ext,
        body,
        frontmatter,
        sourcePath: indexFile.absPath,
    };
}
/**
 * Load every doc source under `rootDir`. Sorted by slug for deterministic
 * output (drift tests, sitemap generation).
 */
export function loadAllDocs(rootDir) {
    return listDocSlugs(rootDir).map((slug) => loadDocSource(rootDir, slug));
}
//# sourceMappingURL=loader.js.map