UNPKG

mdxlayer

Version:

Transform your MDX content into typed, JSON-powered data with flexible schema validation.

85 lines (82 loc) 2.68 kB
import fs from 'node:fs'; import path from 'node:path'; import fg from 'fast-glob'; import matter from 'gray-matter'; import { cache } from '../cache/index.js'; import { getUserConfig } from '../config/index.js'; import { processMDX } from '../plugin/index.js'; import { transformFile } from '../utils/transform.js'; import { toIndexMjs } from './docs/index-js.js'; import { toPackageJson } from './docs/package.js'; import { toTypesDts } from './docs/types-d.js'; const builder = async () => { const { changed, contentDir = "content", docType = "Content", resolvedFields, frontmatterSchema, options } = await getUserConfig(); const cwd = process.cwd(); const dir = path.resolve(cwd, contentDir.replace(/^(\.\/|\/)+/, "")); const files = await fg(["**/*.mdx"], { cwd: dir }); let processedCount = 0; let errorCount = 0; const processingPromises = files.map(async (file) => { const fullPath = path.join(dir, file); const isChanged = cache.mtime(fullPath); if (!isChanged && !changed) { return; } try { const raw = fs.readFileSync(fullPath, "utf8"); const { data, content } = matter(raw); const parsed = frontmatterSchema.safeValidate(data); if (!parsed.success) { throw new Error( `Invalid ${docType} frontmatter in ${file}: ${!parsed.error}` ); } const code = await processMDX(options, content); const filename = file.replace(/\.mdx$/, ""); const doc = { _id: path.basename(filename), ...data, _body: { code, raw: content }, _filePath: fullPath }; if (resolvedFields) { const promises = Object.entries(resolvedFields).map( ([, { resolve }]) => resolve(doc) ); const results = await Promise.all(promises); results.forEach((value, i) => { const key = Object.keys(resolvedFields)[i]; doc[key] = value; }); } transformFile({ doc, filename: `${filename}.json`, subpath: `generated/${docType}` }); processedCount += 1; } catch (err) { console.error(`❌ Error processing ${file}:`, err); errorCount += 1; } }); await Promise.all(processingPromises); toTypesDts({ docType, frontmatterSchema, resolvedFields }); toIndexMjs(files, docType); toPackageJson(); if (errorCount > 0) { console.error(`❌ MDXLayout completed with ${errorCount} errors`); } else if (processedCount > 0) { console.log(`✅ MDXLayout built: ${processedCount} items updated`); } else { console.log("✅ MDXLayout: No changes detected"); } }; export { builder };