bejamas 0.2.4 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{generate-mdx-DW6JH2p8.js → generate-mdx-DppKTXsv.js} +9 -5
- package/dist/generate-mdx-DppKTXsv.js.map +1 -0
- package/dist/index.js +60 -5
- package/dist/index.js.map +1 -1
- package/dist/{utils-BXyPCddm.js → utils-gYZJgF4G.js} +13 -2
- package/dist/utils-gYZJgF4G.js.map +1 -0
- package/package.json +1 -1
- package/dist/generate-mdx-DW6JH2p8.js.map +0 -1
- package/dist/utils-BXyPCddm.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as extractComponentTagsFromMDX, b as logger, c as extractPropsFromDeclaredProps, d as parseJsDocMetadata, f as resolveOutDir, g as getConfig, h as toIdentifier, i as discoverExamples, l as normalizeBlockMDX, m as slugify, n as createSourceFileFromFrontmatter, o as extractFrontmatter, p as resolveUiRoot, r as detectHasImportTopLevel, s as extractPropsFromAstroProps, t as RESERVED_COMPONENTS, u as normalizeUsageMDX, y as spinner } from "./utils-
|
|
1
|
+
import { a as extractComponentTagsFromMDX, b as logger, c as extractPropsFromDeclaredProps, d as parseJsDocMetadata, f as resolveOutDir, g as getConfig, h as toIdentifier, i as discoverExamples, l as normalizeBlockMDX, m as slugify, n as createSourceFileFromFrontmatter, o as extractFrontmatter, p as resolveUiRoot, r as detectHasImportTopLevel, s as extractPropsFromAstroProps, t as RESERVED_COMPONENTS, u as normalizeUsageMDX, y as spinner } from "./utils-gYZJgF4G.js";
|
|
2
2
|
import { createRequire } from "node:module";
|
|
3
3
|
import { dirname, extname, join, relative } from "path";
|
|
4
4
|
import { existsSync, mkdirSync } from "fs";
|
|
@@ -70,7 +70,7 @@ function generateDefaultImports(components, componentsAlias) {
|
|
|
70
70
|
return components.slice().sort().map((name) => `import ${name} from '${componentsAlias}/${name}.astro';`);
|
|
71
71
|
}
|
|
72
72
|
function buildMdx(params) {
|
|
73
|
-
const { importName, importPath, title, description, descriptionBodyMDX, usageMDX, hasImport, propsList, propsTable, examples, examplesBlocks, autoImports, lucideIcons, primaryExampleMDX, componentSource, commandName, figmaUrl, componentsAlias, namedExports } = params;
|
|
73
|
+
const { importName, importPath, title, description, descriptionBodyMDX, usageMDX, hasImport, propsList, propsTable, examples, examplesBlocks, autoImports, lucideIcons, primaryExampleMDX, componentSource, commandName, figmaUrl, componentsAlias, namedExports, apiMDX } = params;
|
|
74
74
|
const useBarrelPattern = isBarrelImport(importPath);
|
|
75
75
|
const sortedLucide = (lucideIcons ?? []).slice().sort();
|
|
76
76
|
const externalTopImports = [`import { Tabs as DocsTabs, TabItem as DocsTabItem } from '@astrojs/starlight/components';`, sortedLucide.length ? `import { ${sortedLucide.join(", ")} } from '@lucide/astro';` : null].filter((v) => v != null).slice().sort((a, b) => String(a).localeCompare(String(b)));
|
|
@@ -293,7 +293,9 @@ ${ex.source}
|
|
|
293
293
|
"",
|
|
294
294
|
propsTable && propsTable.length ? `## Props\n\n| Prop | Type | Default |\n|---|---|---|\n${propsTable.map((p) => `| <code>${p.name}</code> | \`${(p.type || "").replace(/\|/g, "\\|")}\` | ${formatDefault(p.defaultValue)} |`).join("\n")}` : propsList ? `## Props\n\n${propsList}` : null,
|
|
295
295
|
propsTable && propsTable.length || propsList ? "" : null,
|
|
296
|
-
exampleSections.length ? `## Examples\n\n` + exampleSections.join("\n\n") : null
|
|
296
|
+
exampleSections.length ? `## Examples\n\n` + exampleSections.join("\n\n") : null,
|
|
297
|
+
exampleSections.length ? "" : null,
|
|
298
|
+
apiMDX && apiMDX.length ? `## API Reference\n\n${apiMDX}` : null
|
|
297
299
|
].filter((v) => v !== null && v !== void 0).join("\n").trim() + "\n";
|
|
298
300
|
}
|
|
299
301
|
|
|
@@ -420,6 +422,7 @@ async function main() {
|
|
|
420
422
|
const { text: usageMDX, hasImport: hasImportUsage } = normalizeUsageMDX(meta.usageMDX || "", pascal);
|
|
421
423
|
const primaryExampleMDX = normalizeBlockMDX(meta.primaryExampleMDX || "").trim();
|
|
422
424
|
const examplesMDX = normalizeBlockMDX(meta.examplesMDX || "").trim();
|
|
425
|
+
const apiMDX = normalizeBlockMDX(meta.apiMDX || "").trim();
|
|
423
426
|
const hasImportExamples = detectHasImportTopLevel(examplesMDX, pascal);
|
|
424
427
|
const hasImportPrimary = detectHasImportTopLevel(primaryExampleMDX, pascal);
|
|
425
428
|
const hasImport = hasImportUsage || hasImportExamples || hasImportPrimary;
|
|
@@ -473,7 +476,8 @@ async function main() {
|
|
|
473
476
|
figmaUrl,
|
|
474
477
|
descriptionBodyMDX,
|
|
475
478
|
componentsAlias,
|
|
476
|
-
namedExports: isFolder ? usedNamedExports : void 0
|
|
479
|
+
namedExports: isFolder ? usedNamedExports : void 0,
|
|
480
|
+
apiMDX
|
|
477
481
|
});
|
|
478
482
|
const outFile = join(outDir, `${slug}.mdx`);
|
|
479
483
|
mkdirSync(dirname(outFile), { recursive: true });
|
|
@@ -526,4 +530,4 @@ if (process.env.BEJAMAS_SKIP_AUTO_RUN !== "1" && process.env.BEJAMAS_SKIP_AUTO_R
|
|
|
526
530
|
|
|
527
531
|
//#endregion
|
|
528
532
|
export { parseExamplesBlocks, runDocsGenerator };
|
|
529
|
-
//# sourceMappingURL=generate-mdx-
|
|
533
|
+
//# sourceMappingURL=generate-mdx-DppKTXsv.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-mdx-DppKTXsv.js","names":["path","lines: string[]","mainImportLine: string | null","m: RegExpExecArray | null","external: string[]","internal: string[]","exampleSections: string[]","entries: ComponentEntry[]","exports: string[]","match: RegExpExecArray | null","exampleRelPaths: string[]","examples: Array<{\n importName: string;\n importPath: string;\n title: string;\n source: string;\n }>","blocks: Array<{ title: string; body: string[] }>","current: { title: string; body: string[] }"],"sources":["../src/docs/generate-mdx/mdx-builder.ts","../src/docs/generate-mdx/index.ts"],"sourcesContent":["/**\n * Check if an import path uses the new barrel export pattern (no .astro extension)\n */\nfunction isBarrelImport(path: string): boolean {\n return !path.endsWith(\".astro\");\n}\n\n/**\n * Convert a PascalCase component name to its folder path (kebab-case).\n * Examples:\n * - \"Card\" → \"card\"\n * - \"CardHeader\" → \"card\"\n * - \"InputGroup\" → \"input-group\"\n * - \"InputGroupAddon\" → \"input-group\"\n * - \"StickySurface\" → \"sticky-surface\"\n * - \"RadioGroup\" → \"radio-group\"\n * - \"RadioGroupItem\" → \"radio-group\"\n */\nfunction componentToFolder(name: string): string {\n // Known multi-word component families (in PascalCase order)\n // These map to kebab-case folder names\n const multiWordFamilies = [\n \"InputGroup\",\n \"LinkGroup\",\n \"RadioGroup\",\n \"ButtonGroup\",\n \"StickySurface\",\n ];\n\n // Check for multi-word families first (order matters - longer matches first)\n const sortedFamilies = multiWordFamilies.sort((a, b) => b.length - a.length);\n for (const family of sortedFamilies) {\n if (name === family || name.startsWith(family)) {\n // InputGroup → input-group\n return family.replace(/([a-z])([A-Z])/g, \"$1-$2\").toLowerCase();\n }\n }\n\n // For regular names, extract the base component (first PascalCase word)\n // CardHeader → Card → card\n // AvatarFallback → Avatar → avatar\n const baseMatch = name.match(/^[A-Z][a-z]*/);\n return baseMatch ? baseMatch[0].toLowerCase() : name.toLowerCase();\n}\n\n/**\n * Group component names by their folder path\n */\nfunction groupComponentsByFolder(components: string[]): Map<string, string[]> {\n const groups = new Map<string, string[]>();\n for (const comp of components) {\n const folder = componentToFolder(comp);\n if (!groups.has(folder)) {\n groups.set(folder, []);\n }\n groups.get(folder)!.push(comp);\n }\n return groups;\n}\n\n/**\n * Generate import lines for UI components using the barrel import pattern\n */\nfunction generateBarrelImports(\n components: string[],\n componentsAlias: string,\n): string[] {\n const groups = groupComponentsByFolder(components);\n const lines: string[] = [];\n\n // Sort folders alphabetically for consistent output\n const sortedFolders = Array.from(groups.keys()).sort();\n\n for (const folder of sortedFolders) {\n const names = groups.get(folder)!.sort();\n lines.push(\n `import { ${names.join(\", \")} } from '${componentsAlias}/${folder}';`,\n );\n }\n\n return lines;\n}\n\n/**\n * Generate import lines for UI components using the old default import pattern\n */\nfunction generateDefaultImports(\n components: string[],\n componentsAlias: string,\n): string[] {\n return components\n .slice()\n .sort()\n .map((name) => `import ${name} from '${componentsAlias}/${name}.astro';`);\n}\n\nexport function buildMdx(params: {\n importName: string;\n importPath: string;\n title: string;\n description: string;\n descriptionBodyMDX?: string;\n figmaUrl?: string;\n usageMDX: string;\n hasImport: boolean;\n propsList: string;\n propsTable?: Array<{\n name: string;\n type?: string;\n required?: boolean;\n defaultValue?: string | null;\n description?: string | null;\n }>;\n examples: Array<{\n importName: string;\n importPath: string;\n title: string;\n source: string;\n }>;\n examplesBlocks: Array<{ title: string; body: string }>;\n autoImports: string[];\n lucideIcons: string[];\n primaryExampleMDX: string;\n componentSource: string;\n commandName: string;\n componentsAlias: string;\n /**\n * Optional: additional named exports from the main component's barrel.\n * Used when the main component has subcomponents (e.g., Card, CardHeader, CardTitle).\n * If provided, these will be included in the main import statement.\n */\n namedExports?: string[];\n /**\n * Optional: API reference documentation (events, programmatic control, data attributes).\n */\n apiMDX?: string;\n}): string {\n const {\n importName,\n importPath,\n title,\n description,\n descriptionBodyMDX,\n usageMDX,\n hasImport,\n propsList,\n propsTable,\n examples,\n examplesBlocks,\n autoImports,\n lucideIcons,\n primaryExampleMDX,\n componentSource,\n commandName,\n figmaUrl,\n componentsAlias,\n namedExports,\n apiMDX,\n } = params;\n\n // Detect if we should use the new barrel import pattern\n const useBarrelPattern = isBarrelImport(importPath);\n\n const sortedLucide = (lucideIcons ?? []).slice().sort();\n const lucideTopLine = sortedLucide.length\n ? `import { ${sortedLucide.join(\", \")} } from '@lucide/astro';`\n : null;\n const externalTopImports = [\n `import { Tabs as DocsTabs, TabItem as DocsTabItem } from '@astrojs/starlight/components';`,\n lucideTopLine,\n ]\n .filter((v) => v != null)\n .slice()\n .sort((a, b) => String(a).localeCompare(String(b)));\n\n const sortedUiAuto = (autoImports ?? []).slice().sort();\n\n // Generate UI component imports based on pattern\n const uiAutoLines = useBarrelPattern\n ? generateBarrelImports(sortedUiAuto, componentsAlias)\n : generateDefaultImports(sortedUiAuto, componentsAlias);\n\n const exampleLines = (examples ?? [])\n .map((ex) => `import ${ex.importName} from '${ex.importPath}';`)\n .sort((a, b) => a.localeCompare(b));\n\n // Build main component import\n let mainImportLine: string | null = null;\n if (!hasImport) {\n if (useBarrelPattern) {\n // New pattern: named exports\n const exports = [importName, ...(namedExports ?? [])].sort();\n mainImportLine = `import { ${exports.join(\", \")} } from '${importPath}';`;\n } else {\n // Old pattern: default export\n mainImportLine = `import ${importName} from '${importPath}';`;\n }\n }\n\n const internalTopImports = [mainImportLine, ...uiAutoLines, ...exampleLines]\n .filter((v) => v != null)\n .slice()\n .sort((a, b) => String(a).localeCompare(String(b)));\n\n const importLines = [\n ...externalTopImports,\n externalTopImports.length && internalTopImports.length ? \"\" : null,\n ...internalTopImports,\n ].filter((v) => v !== null && v !== undefined);\n\n // Helper: build per-snippet imports so code fences are minimal and copy-pasteable\n const extractTags = (snippet: string): Set<string> => {\n const found = new Set<string>();\n const tagRegex = /<([A-Z][A-Za-z0-9_]*)\\b/g;\n let m: RegExpExecArray | null;\n while ((m = tagRegex.exec(snippet)) !== null) {\n found.add(m[1]);\n }\n return found;\n };\n\n const buildSnippetImportLines = (snippet: string): string[] => {\n if (!snippet || !snippet.length) return [];\n const used = extractTags(snippet);\n const usedIcons = sortedLucide.filter((n) => used.has(n));\n\n // Find UI components used in snippet\n const usedUi = (autoImports ?? []).filter((n) => used.has(n));\n\n // Check if main component (and its subcomponents) are used\n const includeMain = !hasImport && used.has(importName);\n\n // For new pattern, also check for subcomponents from the main barrel\n const usedNamedExports =\n useBarrelPattern && namedExports\n ? namedExports.filter((n) => used.has(n))\n : [];\n\n const external: string[] = [];\n if (usedIcons.length) {\n external.push(`import { ${usedIcons.join(\", \")} } from '@lucide/astro';`);\n }\n\n const internal: string[] = [];\n\n if (useBarrelPattern) {\n // New pattern: group by folder and use named imports\n\n // Main component and its subcomponents\n if (includeMain || usedNamedExports.length > 0) {\n const mainExports = [\n ...(includeMain ? [importName] : []),\n ...usedNamedExports,\n ].sort();\n internal.push(\n `import { ${mainExports.join(\", \")} } from '${importPath}';`,\n );\n }\n\n // Other UI components grouped by folder\n if (usedUi.length > 0) {\n internal.push(...generateBarrelImports(usedUi, componentsAlias));\n }\n } else {\n // Old pattern: default imports\n if (includeMain) {\n internal.push(`import ${importName} from '${importPath}';`);\n }\n internal.push(\n ...usedUi\n .slice()\n .sort()\n .map(\n (name) => `import ${name} from '${componentsAlias}/${name}.astro';`,\n ),\n );\n }\n\n const externalSorted = external.slice().sort((a, b) => a.localeCompare(b));\n const internalSorted = internal.slice().sort((a, b) => a.localeCompare(b));\n return [\n ...externalSorted,\n externalSorted.length && internalSorted.length ? \"\" : null,\n ...internalSorted,\n ].filter((v) => v !== null && v !== undefined) as string[];\n };\n\n const wrapTextNodes = (snippet: string): string => {\n if (!snippet) return snippet;\n return snippet.replace(/>([^<]+)</g, (match, inner) => {\n const trimmed = inner.trim();\n if (!trimmed.length) return match;\n // Skip if the entire trimmed content is a JSX expression\n if (/^\\{[\\s\\S]*\\}$/.test(trimmed)) return match;\n // Skip if the content already contains JSX expressions (e.g., \"Use{\\\" \\\"}\" or mixed content)\n // This prevents double-wrapping and breaking inline JSX whitespace expressions\n if (/\\{[^}]*\\}/.test(inner)) return match;\n return `>{${JSON.stringify(inner)}}<`;\n });\n };\n\n /**\n * Normalize whitespace in preview content.\n * This collapses ALL newlines and multiple spaces into single spaces to prevent\n * MDX parsing issues. In particular, a '>' at the start of a line is interpreted\n * as a block quote marker by MDX, which causes \"Unexpected lazy line\" errors.\n */\n const normalizeInlineWhitespace = (snippet: string): string => {\n if (!snippet) return snippet;\n // Collapse ALL newlines and multiple whitespace into single spaces\n // This prevents MDX from interpreting '>' at start of line as block quote\n return snippet.replace(/\\s+/g, \" \").trim();\n };\n\n /**\n * Convert <p> tags that contain component tags to <span> tags.\n * This is necessary because components may render as block elements (like <div>),\n * and HTML doesn't allow block elements inside <p>. The browser would automatically\n * close the <p> before any block element, breaking the layout.\n */\n const convertParagraphsWithComponents = (snippet: string): string => {\n if (!snippet) return snippet;\n // Detect if a <p> tag contains component tags (PascalCase like <KbdGroup>)\n // If so, convert <p> to <span> to allow block-level children\n return snippet.replace(\n /<p(\\s[^>]*)?>([^]*?)<\\/p>/gi,\n (match, attrs, content) => {\n // Check if content contains component tags (PascalCase)\n if (/<[A-Z][A-Za-z0-9]*/.test(content)) {\n // Convert to span with inline-block display to preserve paragraph-like behavior\n const spanAttrs = attrs || \"\";\n return `<span${spanAttrs} style=\"display:block\">${content}</span>`;\n }\n return match;\n },\n );\n };\n\n const toMdxPreview = (snippet: string): string => {\n if (!snippet) return snippet;\n // Convert HTML comments to MDX comment blocks for preview sections\n const withoutComments = snippet.replace(/<!--([\\s\\S]*?)-->/g, \"{/*$1*/}\");\n // Convert <p> tags containing components to <span> to avoid HTML validity issues\n const withConvertedParagraphs =\n convertParagraphsWithComponents(withoutComments);\n // If the snippet contains user-defined <p> elements, preserve structure as-is\n if (/<p[\\s>]/i.test(withConvertedParagraphs)) {\n return normalizeInlineWhitespace(withConvertedParagraphs);\n }\n // Normalize whitespace to prevent MDX from splitting inline text into paragraphs\n const normalized = normalizeInlineWhitespace(withConvertedParagraphs);\n return wrapTextNodes(normalized);\n };\n\n // Split an example body into leading markdown description (paragraphs)\n // and the Astro/HTML snippet that should be rendered in Preview/Source tabs\n const splitDescriptionAndSnippet = (\n body: string,\n ): { descriptionMD: string; snippet: string } => {\n if (!body || !body.trim().length) return { descriptionMD: \"\", snippet: \"\" };\n const lines = body.split(\"\\n\");\n let snippetStartIdx = -1;\n for (let i = 0; i < lines.length; i++) {\n const ln = lines[i];\n // Skip empty lines before first meaningful content\n if (!ln.trim().length) continue;\n // Heuristic: consider this line the start of the snippet if it looks like Astro/HTML/JSX\n // e.g. starts with '<' or '{'\n if (/^\\s*[<{]/.test(ln)) {\n snippetStartIdx = i;\n break;\n }\n // Otherwise it's part of markdown description; keep looking until we hit markup\n }\n if (snippetStartIdx <= 0) {\n // No clear description or snippet starts at the very beginning → treat all as snippet\n return { descriptionMD: \"\", snippet: body.trim() };\n }\n const descriptionMD = lines.slice(0, snippetStartIdx).join(\"\\n\").trim();\n const snippet = lines.slice(snippetStartIdx).join(\"\\n\").trim();\n return { descriptionMD, snippet };\n };\n\n const primaryExampleSection =\n primaryExampleMDX && primaryExampleMDX.length\n ? `<div class=\"not-content sl-bejamas-component-preview flex justify-center px-4 md:px-10 py-12 border border-border rounded-t-lg min-h-72 items-center [&_input]:max-w-xs\">\n${toMdxPreview(primaryExampleMDX)}\n</div>\n\n\\`\\`\\`astro\n${(() => {\n const lines = buildSnippetImportLines(primaryExampleMDX);\n return lines.length ? `---\\n${lines.join(\"\\n\")}\\n---\\n\\n` : \"\";\n})()}${primaryExampleMDX}\n\\`\\`\\``\n : null;\n\n const exampleSections: string[] = [];\n if (examplesBlocks && examplesBlocks.length) {\n for (const blk of examplesBlocks) {\n const { descriptionMD, snippet } = splitDescriptionAndSnippet(blk.body);\n const previewBody = toMdxPreview(snippet);\n\n // If there's no snippet, render only header + description\n if (!snippet || !snippet.length) {\n exampleSections.push(\n `### ${blk.title}\n\n${descriptionMD}`.trim(),\n );\n continue;\n }\n\n exampleSections.push(\n `### ${blk.title}\n\n${descriptionMD ? `${descriptionMD}\\n\\n` : \"\"}<div class=\"not-content sl-bejamas-component-preview flex justify-center px-4 md:px-10 py-12 border border-border rounded-t-lg min-h-72 items-center [&_input]:max-w-xs\">\n${previewBody}\n</div>\n\n\\`\\`\\`astro\n${(() => {\n const lines = buildSnippetImportLines(snippet);\n return lines.length ? `---\\n${lines.join(\"\\n\")}\\n---\\n\\n` : \"\";\n})()}${snippet}\n\\`\\`\\``,\n );\n }\n }\n if (examples && examples.length) {\n for (const ex of examples) {\n exampleSections.push(\n `### ${ex.title}\n\n<div class=\"not-content\">\n <${ex.importName} />\n</div>\n\n\\`\\`\\`astro\n${ex.source}\n\\`\\`\\``,\n );\n }\n }\n\n const formatDefault = (val: unknown): string => {\n if (val == null) return \"\";\n let raw = String(val).trim();\n if (!raw.length) return \"\";\n // Normalize curly quotes to ASCII\n raw = raw\n .replace(/[\\u201C\\u201D\\u201E\\u201F]/g, '\"')\n .replace(/[\\u2018\\u2019]/g, \"'\");\n const isSingleQuoted = /^'[^']*'$/.test(raw);\n const isDoubleQuoted = /^\"[^\"]*\"$/.test(raw);\n const isBacktickSimple = /^`[^`]*`$/.test(raw) && raw.indexOf(\"${\") === -1;\n\n let content = raw;\n if (isSingleQuoted || isDoubleQuoted || isBacktickSimple) {\n const inner = raw.slice(1, -1);\n // Re-quote with standard double quotes\n content = `\"${inner}\"`;\n }\n // Escape table pipes\n content = content.replace(/\\|/g, \"\\\\|\");\n // Choose a backtick fence that doesn't appear in content\n const hasTick = content.includes(\"`\");\n const hasDoubleTick = content.includes(\"``\");\n const fence = !hasTick ? \"`\" : !hasDoubleTick ? \"``\" : \"```\";\n return `${fence}${content}${fence}`;\n };\n\n const installationSection = `## Installation\n\n<DocsTabs syncKey=\"pkg\">\n <DocsTabItem label=\"bun\">\n \\`\\`\\`bash\n bunx bejamas add ${commandName}\n \\`\\`\\`\n </DocsTabItem>\n <DocsTabItem label=\"npm\">\n \\`\\`\\`bash\n npx bejamas add ${commandName}\n \\`\\`\\`\n </DocsTabItem>\n <DocsTabItem label=\"pnpm\">\n \\`\\`\\`bash\n pnpm dlx bejamas add ${commandName}\n \\`\\`\\`\n </DocsTabItem>\n <DocsTabItem label=\"yarn\">\n \\`\\`\\`bash\n yarn dlx bejamas add ${commandName}\n \\`\\`\\`\n </DocsTabItem>\n</DocsTabs>`;\n\n const serializeFrontmatter = (\n label: string,\n value?: string,\n ): string | null => {\n if (!value || !value.length) return null;\n return `${label}: ${JSON.stringify(value)}`;\n };\n\n const lines = [\n \"---\",\n serializeFrontmatter(\"title\", title),\n serializeFrontmatter(\"description\", description),\n serializeFrontmatter(\"figmaUrl\", figmaUrl),\n \"---\",\n \"\",\n ...importLines,\n importLines.length ? \"\" : null,\n descriptionBodyMDX && descriptionBodyMDX.length ? descriptionBodyMDX : null,\n descriptionBodyMDX && descriptionBodyMDX.length ? \"\" : null,\n primaryExampleSection,\n primaryExampleSection ? \"\" : null,\n installationSection,\n \"\",\n usageMDX && usageMDX.length ? `## Usage\\n\\n${usageMDX}` : null,\n \"\",\n propsTable && propsTable.length\n ? `## Props\\n\\n| Prop | Type | Default |\\n|---|---|---|\\n${propsTable\n .map(\n (p) =>\n `| <code>${p.name}</code> | \\`${(p.type || \"\").replace(/\\|/g, \"\\\\|\")}\\` | ${formatDefault(p.defaultValue)} |`,\n )\n .join(\"\\n\")}`\n : propsList\n ? `## Props\\n\\n${propsList}`\n : null,\n (propsTable && propsTable.length) || propsList ? \"\" : null,\n exampleSections.length\n ? `## Examples\\n\\n` + exampleSections.join(\"\\n\\n\")\n : null,\n exampleSections.length ? \"\" : null,\n apiMDX && apiMDX.length ? `## API Reference\\n\\n${apiMDX}` : null,\n ].filter((v) => v !== null && v !== undefined);\n\n return lines.join(\"\\n\").trim() + \"\\n\";\n}\n","import { mkdirSync, existsSync } from \"fs\";\nimport { readdir, readFile, writeFile } from \"fs/promises\";\nimport { join, extname, dirname, relative, basename } from \"path\";\nimport {\n RESERVED_COMPONENTS,\n slugify,\n extractFrontmatter,\n toIdentifier,\n parseJsDocMetadata,\n extractPropsFromAstroProps,\n extractPropsFromDeclaredProps,\n resolveUiRoot,\n resolveOutDir,\n normalizeUsageMDX,\n normalizeBlockMDX,\n detectHasImportTopLevel,\n discoverExamples,\n extractComponentTagsFromMDX,\n createSourceFileFromFrontmatter,\n} from \"./utils\";\nimport { buildMdx } from \"./mdx-builder\";\nimport { logger } from \"@/src/utils/logger\";\nimport { spinner } from \"@/src/utils/spinner\";\nimport { getConfig } from \"@/src/utils/get-config\";\n\ninterface ComponentEntry {\n /** The main component name (PascalCase), e.g., \"Card\" */\n name: string;\n /** Path to the main .astro file */\n filePath: string;\n /** The folder name (lowercase/kebab-case), e.g., \"card\" */\n folderName: string;\n /** Whether this is a folder-based component with barrel exports */\n isFolder: boolean;\n /** List of subcomponent names exported from the barrel, e.g., [\"CardHeader\", \"CardTitle\"] */\n namedExports: string[];\n}\n\n/**\n * Discover components in the components directory.\n * Supports both:\n * - Old pattern: flat .astro files in components/\n * - New pattern: folders with index.ts barrel exports\n */\nasync function discoverComponents(\n componentsDir: string,\n): Promise<ComponentEntry[]> {\n const entries: ComponentEntry[] = [];\n const dirEntries = await readdir(componentsDir, { withFileTypes: true });\n\n for (const entry of dirEntries) {\n if (entry.isDirectory()) {\n // New pattern: folder with barrel exports\n const folderPath = join(componentsDir, entry.name);\n const indexPath = join(folderPath, \"index.ts\");\n\n if (existsSync(indexPath)) {\n // Parse the barrel file to find exports\n const indexContent = await readFile(indexPath, \"utf-8\");\n const namedExports = parseBarrelExports(indexContent);\n\n // Find the main component (first export or the one matching folder name)\n const mainComponentName = findMainComponent(namedExports, entry.name);\n\n if (mainComponentName) {\n const mainFilePath = join(folderPath, `${mainComponentName}.astro`);\n\n if (existsSync(mainFilePath)) {\n // Filter out the main component from namedExports (it will be imported separately)\n const subComponents = namedExports.filter(\n (n) => n !== mainComponentName,\n );\n\n entries.push({\n name: mainComponentName,\n filePath: mainFilePath,\n folderName: entry.name,\n isFolder: true,\n namedExports: subComponents,\n });\n }\n }\n }\n } else if (entry.isFile() && extname(entry.name).toLowerCase() === \".astro\") {\n // Old pattern: flat .astro file\n const componentName = entry.name.replace(/\\.astro$/i, \"\");\n entries.push({\n name: componentName,\n filePath: join(componentsDir, entry.name),\n folderName: \"\",\n isFolder: false,\n namedExports: [],\n });\n }\n }\n\n return entries;\n}\n\n/**\n * Parse a barrel (index.ts) file to extract named exports.\n * Handles patterns like:\n * - export { default as Card } from \"./Card.astro\";\n * - export { default as CardHeader } from \"./CardHeader.astro\";\n */\nfunction parseBarrelExports(content: string): string[] {\n const exports: string[] = [];\n\n // Match: export { default as ComponentName } from \"...\"\n const exportRegex = /export\\s*\\{\\s*default\\s+as\\s+(\\w+)\\s*\\}/g;\n let match: RegExpExecArray | null;\n\n while ((match = exportRegex.exec(content)) !== null) {\n exports.push(match[1]);\n }\n\n return exports;\n}\n\n/**\n * Find the main component from a list of exports.\n * The main component is typically the one that matches the folder name (PascalCase).\n */\nfunction findMainComponent(\n exports: string[],\n folderName: string,\n): string | null {\n if (exports.length === 0) return null;\n\n // Convert folder name to PascalCase for comparison\n // e.g., \"card\" -> \"Card\", \"input-group\" -> \"InputGroup\"\n const expectedName = folderName\n .split(\"-\")\n .map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n .join(\"\");\n\n // First, try to find exact match\n const exactMatch = exports.find((e) => e === expectedName);\n if (exactMatch) return exactMatch;\n\n // Otherwise, return the first export (usually the main component)\n return exports[0];\n}\n\nasync function main() {\n const DEBUG =\n process.env.BEJAMAS_DEBUG === \"1\" || process.env.BEJAMAS_DEBUG === \"true\";\n const cwd =\n process.env.BEJAMAS_DOCS_CWD && process.env.BEJAMAS_DOCS_CWD.length\n ? (process.env.BEJAMAS_DOCS_CWD as string)\n : process.cwd();\n const config = await getConfig(cwd);\n const componentsAlias = (\n config?.aliases?.ui ||\n config?.aliases?.components ||\n \"@bejamas/ui/components\"\n ).replace(/\\/$/, \"\");\n const componentsDirFromConfig =\n config?.resolvedPaths?.ui || config?.resolvedPaths?.components;\n let uiRoot = resolveUiRoot(cwd);\n let componentsDir = join(uiRoot, \"src\", \"components\");\n if (componentsDirFromConfig) {\n componentsDir = componentsDirFromConfig;\n uiRoot = dirname(dirname(componentsDirFromConfig));\n }\n if (!existsSync(componentsDir)) {\n // Fallback to ui package components if the configured path is missing.\n componentsDir = join(uiRoot, \"src\", \"components\");\n }\n const outDir = resolveOutDir(cwd);\n mkdirSync(outDir, { recursive: true });\n\n if (DEBUG) {\n logger.info(`[docs-generator] cwd: ${cwd}`);\n logger.info(`[docs-generator] uiRoot: ${uiRoot}`);\n logger.info(`[docs-generator] componentsDir: ${componentsDir}`);\n logger.info(`[docs-generator] outDir: ${outDir}`);\n }\n\n // Discover all components (both flat files and folders)\n const components = await discoverComponents(componentsDir);\n\n if (DEBUG) {\n logger.info(`[docs-generator] components found: ${components.length}`);\n if (components.length) {\n logger.info(\n `[docs-generator] first few: ${components\n .slice(0, 5)\n .map((c) => c.name)\n .join(\", \")}`,\n );\n }\n }\n\n let generatedCount = 0;\n const total = components.length;\n const spin = spinner(`Generating docs (0/${total})`).start();\n\n for (const component of components) {\n const { name: pascal, filePath, folderName, isFolder, namedExports } = component;\n\n const astroFile = await readFile(filePath, \"utf-8\");\n const frontmatterCode = extractFrontmatter(astroFile);\n const sourceFile = createSourceFileFromFrontmatter(frontmatterCode);\n const meta = parseJsDocMetadata(frontmatterCode);\n const declaredProps = extractPropsFromDeclaredProps(sourceFile);\n const destructuredProps = extractPropsFromAstroProps(sourceFile);\n\n // Build props table preferring declared types; merge defaults from destructuring\n const defaultsMap = new Map<string, string | null>();\n for (const p of destructuredProps) {\n if (p.name && p.hasDefault) {\n defaultsMap.set(p.name, p.defaultValue || null);\n }\n }\n\n const propsTable = (declaredProps.length ? declaredProps : []).map((p) => ({\n name: p.name,\n type: p.type,\n required: !p.optional,\n defaultValue: defaultsMap.has(p.name) ? defaultsMap.get(p.name)! : null,\n }));\n\n const slug = slugify(pascal);\n const title = meta.title || meta.name || pascal;\n const description = meta.description || \"\";\n const descriptionBodyMDX = (meta as any).descriptionBodyMDX || \"\";\n const figmaUrl = (meta as any).figmaUrl || \"\";\n // Do not display props if there is no declared Props\n const propsList = \"\";\n\n const importName = pascal;\n // Use folder-based barrel import for new pattern, file-based for old pattern\n const importPath = isFolder\n ? `${componentsAlias}/${folderName}`\n : `${componentsAlias}/${pascal}.astro`;\n\n const { text: usageMDX, hasImport: hasImportUsage } = normalizeUsageMDX(\n meta.usageMDX || \"\",\n pascal,\n );\n const primaryExampleMDX = normalizeBlockMDX(\n meta.primaryExampleMDX || \"\",\n ).trim();\n const examplesMDX = normalizeBlockMDX(meta.examplesMDX || \"\").trim();\n const apiMDX = normalizeBlockMDX(meta.apiMDX || \"\").trim();\n const hasImportExamples = detectHasImportTopLevel(examplesMDX, pascal);\n const hasImportPrimary = detectHasImportTopLevel(primaryExampleMDX, pascal);\n const hasImport = hasImportUsage || hasImportExamples || hasImportPrimary;\n\n let exampleRelPaths: string[] = [];\n let examples: Array<{\n importName: string;\n importPath: string;\n title: string;\n source: string;\n }> = [];\n const examplesBlocksRaw = examplesMDX;\n const examplesBlocks = parseExamplesBlocks(examplesBlocksRaw);\n if (examplesBlocks.length === 0) {\n exampleRelPaths = await discoverExamples(filePath, componentsDir);\n examples = (exampleRelPaths || []).map((rel) => {\n const posixRel = rel\n .split(require(\"path\").sep)\n .join(require(\"path\").posix.sep);\n const importPathEx = `${componentsAlias}/${posixRel}`;\n const abs = join(componentsDir, rel);\n const source = require(\"fs\").readFileSync(abs, \"utf-8\");\n const base = toIdentifier(\n require(\"path\").basename(rel, require(\"path\").extname(rel)),\n );\n const importNameEx = `${pascal}${base}`;\n const titleEx = base;\n return { importName: importNameEx, importPath: importPathEx, title: titleEx, source };\n });\n }\n\n const usedInUsage = extractComponentTagsFromMDX(usageMDX).filter(\n (n) => n !== pascal,\n );\n const usedInExamples = extractComponentTagsFromMDX(examplesMDX).filter(\n (n) => n !== pascal,\n );\n const usedInPrimary = extractComponentTagsFromMDX(primaryExampleMDX).filter(\n (n) => n !== pascal,\n );\n const autoSet = new Set<string>([\n ...usedInUsage,\n ...usedInExamples,\n ...usedInPrimary,\n ]);\n\n // For folder-based components, add subcomponents used in examples to namedExports\n const usedNamedExports = isFolder\n ? namedExports.filter((n) => autoSet.has(n))\n : [];\n\n // Remove subcomponents from autoSet (they'll be included via namedExports)\n if (isFolder) {\n for (const n of namedExports) {\n autoSet.delete(n);\n }\n }\n\n const autoImports = Array.from(autoSet)\n .filter((name) => !RESERVED_COMPONENTS.has(name))\n .filter((name) => true);\n\n const lucideIcons = autoImports.filter((n) => /Icon$/.test(n));\n const uiAutoImports = autoImports.filter((n) => !/Icon$/.test(n));\n\n const mdx = buildMdx({\n importName,\n importPath,\n title,\n description,\n usageMDX,\n hasImport,\n propsList,\n propsTable,\n examples,\n examplesBlocks: parseExamplesBlocks(examplesBlocksRaw),\n autoImports: uiAutoImports,\n lucideIcons,\n primaryExampleMDX,\n componentSource: astroFile.trim(),\n commandName: slug,\n figmaUrl,\n descriptionBodyMDX,\n componentsAlias,\n // Pass subcomponents as named exports for folder-based components\n namedExports: isFolder ? usedNamedExports : undefined,\n apiMDX,\n });\n const outFile = join(outDir, `${slug}.mdx`);\n mkdirSync(dirname(outFile), { recursive: true });\n await writeFile(outFile, mdx, \"utf-8\");\n generatedCount += 1;\n spin.text = `Generating docs (${generatedCount}/${total}) - ${title}`;\n if (DEBUG) logger.info(`Generated ${outFile}`);\n }\n spin.succeed(\n `Created ${generatedCount} file${generatedCount === 1 ? \"\" : \"s\"}:`,\n );\n // log all files with relative paths, sorted alphabetically\n const relPaths = components\n .map((c) => {\n const slug = slugify(c.name);\n const outFile = join(outDir, `${slug}.mdx`);\n return relative(cwd, outFile);\n })\n .sort((a, b) => a.localeCompare(b));\n relPaths.forEach((p) => {\n logger.log(` - ${p}`);\n });\n logger.break();\n}\n\nexport function parseExamplesBlocks(\n examplesMDX: string,\n): Array<{ title: string; body: string }> {\n if (!examplesMDX) return [];\n const lines = examplesMDX.split(\"\\n\");\n const blocks: Array<{ title: string; body: string[] }> = [];\n let current: { title: string; body: string[] } = { title: \"\", body: [] };\n for (const line of lines) {\n const heading = line.match(/^###\\s+(.+)$/);\n if (heading) {\n if (current.title || current.body.length) blocks.push(current);\n current = { title: heading[1].trim(), body: [] };\n continue;\n }\n current.body.push(line);\n }\n if (current.title || current.body.length) blocks.push(current);\n return blocks.map((b, idx) => ({\n title: b.title || `Example ${idx + 1}`,\n body: b.body.join(\"\\n\").trim(),\n }));\n}\n\nexport async function runDocsGenerator(): Promise<void> {\n await main();\n}\n\nif (\n process.env.BEJAMAS_SKIP_AUTO_RUN !== \"1\" &&\n process.env.BEJAMAS_SKIP_AUTO_RUN !== \"true\"\n) {\n runDocsGenerator().catch((err) => {\n logger.error(String(err));\n process.exit(1);\n });\n}\n"],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { S as BASE_COLORS, _ as getWorkspaceConfig, b as logger, d as parseJsDocMetadata, g as getConfig, o as extractFrontmatter, p as resolveUiRoot, v as getProjectInfo, x as highlighter, y as spinner } from "./utils-
|
|
2
|
+
import { S as BASE_COLORS, _ as getWorkspaceConfig, b as logger, d as parseJsDocMetadata, g as getConfig, o as extractFrontmatter, p as resolveUiRoot, v as getProjectInfo, x as highlighter, y as spinner } from "./utils-gYZJgF4G.js";
|
|
3
3
|
import { Command } from "commander";
|
|
4
4
|
import { createRequire } from "module";
|
|
5
5
|
import path from "path";
|
|
@@ -523,7 +523,7 @@ async function generateDocs({ cwd, outDir, verbose }) {
|
|
|
523
523
|
if (process.env.BEJAMAS_DOCS_CWD) logger.info(`Docs CWD: ${process.env.BEJAMAS_DOCS_CWD}`);
|
|
524
524
|
if (process.env.BEJAMAS_DOCS_OUT_DIR) logger.info(`Docs out: ${process.env.BEJAMAS_DOCS_OUT_DIR}`);
|
|
525
525
|
}
|
|
526
|
-
const mod = await import("./generate-mdx-
|
|
526
|
+
const mod = await import("./generate-mdx-DppKTXsv.js");
|
|
527
527
|
if (typeof mod.runDocsGenerator === "function") await mod.runDocsGenerator();
|
|
528
528
|
else throw new Error("Failed to load docs generator. Export 'runDocsGenerator' not found.");
|
|
529
529
|
} catch (err) {
|
|
@@ -997,6 +997,44 @@ function rewritePaths(paths, mapResult) {
|
|
|
997
997
|
return filePath;
|
|
998
998
|
});
|
|
999
999
|
}
|
|
1000
|
+
/** Fetch available components from the registry */
|
|
1001
|
+
async function fetchAvailableComponents(registryUrl) {
|
|
1002
|
+
const indexUrl = `${registryUrl}/index.json`;
|
|
1003
|
+
const response = await fetch(indexUrl);
|
|
1004
|
+
if (!response.ok) throw new Error(`Failed to fetch registry index: ${response.statusText}`);
|
|
1005
|
+
const data = await response.json();
|
|
1006
|
+
return Array.isArray(data) ? data : [];
|
|
1007
|
+
}
|
|
1008
|
+
/** Prompt user to select components interactively */
|
|
1009
|
+
async function promptForComponents(registryUrl) {
|
|
1010
|
+
const checkingSpinner = spinner("Checking registry.").start();
|
|
1011
|
+
let components;
|
|
1012
|
+
try {
|
|
1013
|
+
components = await fetchAvailableComponents(registryUrl);
|
|
1014
|
+
checkingSpinner.succeed();
|
|
1015
|
+
} catch (error) {
|
|
1016
|
+
checkingSpinner.fail();
|
|
1017
|
+
logger.error("Failed to fetch available components from registry.");
|
|
1018
|
+
return null;
|
|
1019
|
+
}
|
|
1020
|
+
if (components.length === 0) {
|
|
1021
|
+
logger.warn("No components available in registry.");
|
|
1022
|
+
return null;
|
|
1023
|
+
}
|
|
1024
|
+
const { selected } = await prompts({
|
|
1025
|
+
type: "autocompleteMultiselect",
|
|
1026
|
+
name: "selected",
|
|
1027
|
+
message: "Which components would you like to add?",
|
|
1028
|
+
choices: components.filter((c) => !c.type || c.type === "registry:ui").map((c) => ({
|
|
1029
|
+
title: c.name,
|
|
1030
|
+
value: c.name
|
|
1031
|
+
})),
|
|
1032
|
+
hint: "- Space to select. Return to submit.",
|
|
1033
|
+
instructions: false
|
|
1034
|
+
});
|
|
1035
|
+
if (!selected) return null;
|
|
1036
|
+
return selected;
|
|
1037
|
+
}
|
|
1000
1038
|
/** Parse shadcn output to extract file lists (stdout has paths, stderr has headers) */
|
|
1001
1039
|
function parseShadcnOutput(stdout, stderr) {
|
|
1002
1040
|
const result = {
|
|
@@ -1094,8 +1132,27 @@ const add = new Command().name("add").description("Add components via shadcn@lat
|
|
|
1094
1132
|
const forwardedOptions = extractOptionsForShadcn(process.argv.slice(2), cmd);
|
|
1095
1133
|
const opts = typeof cmd.optsWithGlobals === "function" ? cmd.optsWithGlobals() : cmd.opts?.() ?? {};
|
|
1096
1134
|
const cwd = opts.cwd || process.cwd();
|
|
1097
|
-
|
|
1135
|
+
let componentsToAdd = packages || [];
|
|
1136
|
+
const wantsAll = Boolean(opts.all);
|
|
1137
|
+
const isSilent = opts.silent || false;
|
|
1098
1138
|
const registryUrl = process.env.REGISTRY_URL || DEFAULT_REGISTRY_URL;
|
|
1139
|
+
if (wantsAll && componentsToAdd.length === 0) {
|
|
1140
|
+
const fetchingSpinner = spinner("Fetching available components.", { silent: isSilent }).start();
|
|
1141
|
+
try {
|
|
1142
|
+
componentsToAdd = (await fetchAvailableComponents(registryUrl)).filter((c) => !c.type || c.type === "registry:ui").map((c) => c.name);
|
|
1143
|
+
fetchingSpinner.succeed();
|
|
1144
|
+
} catch (error) {
|
|
1145
|
+
fetchingSpinner.fail();
|
|
1146
|
+
logger.error("Failed to fetch available components from registry.");
|
|
1147
|
+
process.exit(1);
|
|
1148
|
+
}
|
|
1149
|
+
}
|
|
1150
|
+
if (componentsToAdd.length === 0) {
|
|
1151
|
+
const selected = await promptForComponents(registryUrl);
|
|
1152
|
+
if (!selected || selected.length === 0) return;
|
|
1153
|
+
componentsToAdd = selected;
|
|
1154
|
+
}
|
|
1155
|
+
const config = await getConfig(cwd);
|
|
1099
1156
|
let uiDir = config?.resolvedPaths?.ui || "";
|
|
1100
1157
|
let uiConfig = config;
|
|
1101
1158
|
if (config) {
|
|
@@ -1110,8 +1167,6 @@ const add = new Command().name("add").description("Add components via shadcn@lat
|
|
|
1110
1167
|
logger.info(`[bejamas-ui] uiDir: ${uiDir}`);
|
|
1111
1168
|
logger.info(`[bejamas-ui] aliases.ui: ${uiConfig?.aliases?.ui || "not set"}`);
|
|
1112
1169
|
}
|
|
1113
|
-
const isSilent = opts.silent || false;
|
|
1114
|
-
const componentsToAdd = packages || [];
|
|
1115
1170
|
const totalComponents = componentsToAdd.length;
|
|
1116
1171
|
for (let i = 0; i < componentsToAdd.length; i++) {
|
|
1117
1172
|
const component = componentsToAdd[i];
|