bejamas 0.2.4 → 0.2.5

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.
@@ -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-BXyPCddm.js";
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-YFyZFTwZ.js";
2
2
  import { createRequire } from "node:module";
3
3
  import { dirname, extname, join, relative } from "path";
4
4
  import { existsSync, mkdirSync } from "fs";
@@ -526,4 +526,4 @@ if (process.env.BEJAMAS_SKIP_AUTO_RUN !== "1" && process.env.BEJAMAS_SKIP_AUTO_R
526
526
 
527
527
  //#endregion
528
528
  export { parseExamplesBlocks, runDocsGenerator };
529
- //# sourceMappingURL=generate-mdx-DW6JH2p8.js.map
529
+ //# sourceMappingURL=generate-mdx-QQQyHF4o.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"generate-mdx-DW6JH2p8.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}): 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 } = 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 ].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 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 });\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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"}
1
+ {"version":3,"file":"generate-mdx-QQQyHF4o.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}): 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 } = 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 ].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 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 });\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-BXyPCddm.js";
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-YFyZFTwZ.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-DW6JH2p8.js");
526
+ const mod = await import("./generate-mdx-QQQyHF4o.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
- const config = await getConfig(cwd);
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];
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["errors: Record<string, boolean>","fs","ERRORS.MISSING_DIR_OR_EMPTY_PROJECT","context: RegistryContext","template: keyof typeof TEMPLATES","projectName: string","fs","TEMPLATE_TAR_SUBPATH: Record<keyof typeof TEMPLATES, string>","headers: Record<string, string>","DEFAULT_REGISTRY_URL","ERRORS.MISSING_DIR_OR_EMPTY_PROJECT","baseUrl: string","paths: Record<string, string[] | string>","probe: string | null","mapped: string","uiAbs: string | null","cssAbs: string | null","outResolved: string | null","relative","err: any","FIELD_LABELS: Record<string, string>","missingRequired: string[]","missingRecommended: string[]","status: \"complete\" | \"incomplete\" | \"missing\"","probe: string | null","mapped: string","uiAbs: string | null","cssAbs: string | null","uiRoot: string","join","extname","results: ComponentDocStatus[]","checkResult: CheckResult","err: any","path","dirname","path","result: ReorganizeResult","forwarded: string[]","addIndex","rest","forwarded","files: string[]","path","currentSubfolder: string | null","result: ParsedOutput","allPaths: string[]","autoFlags: string[]","args: string[]"],"sources":["../src/utils/errors.ts","../src/preflights/preflight-init.ts","../src/registry/context.ts","../src/utils/get-package-manager.ts","../src/registry/errors.ts","../src/utils/handle-error.ts","../src/utils/create-project.ts","../src/commands/init.ts","../src/utils/tsconfig-utils.ts","../src/commands/docs.ts","../src/commands/docs-check.ts","../src/utils/astro-imports.ts","../src/utils/reorganize-components.ts","../src/commands/add.ts","../src/index.ts"],"sourcesContent":["export const MISSING_DIR_OR_EMPTY_PROJECT = \"1\";\nexport const EXISTING_CONFIG = \"2\";\nexport const MISSING_CONFIG = \"3\";\nexport const FAILED_CONFIG_READ = \"4\";\nexport const TAILWIND_NOT_CONFIGURED = \"5\";\nexport const IMPORT_ALIAS_MISSING = \"6\";\nexport const UNSUPPORTED_FRAMEWORK = \"7\";\nexport const COMPONENT_URL_NOT_FOUND = \"8\";\nexport const COMPONENT_URL_UNAUTHORIZED = \"9\";\nexport const COMPONENT_URL_FORBIDDEN = \"10\";\nexport const COMPONENT_URL_BAD_REQUEST = \"11\";\nexport const COMPONENT_URL_INTERNAL_SERVER_ERROR = \"12\";\nexport const BUILD_MISSING_REGISTRY_FILE = \"13\";\n","import path from \"path\";\nimport { initOptionsSchema } from \"@/src/commands/init\";\nimport * as ERRORS from \"@/src/utils/errors\";\nimport fs from \"fs-extra\";\nimport { z } from \"zod\";\n\nexport async function preFlightInit(\n options: z.infer<typeof initOptionsSchema>,\n) {\n const errors: Record<string, boolean> = {};\n\n // Ensure target directory exists.\n // Check for empty project. We assume if no package.json exists, the project is empty.\n if (\n !fs.existsSync(options.cwd) ||\n !fs.existsSync(path.resolve(options.cwd, \"package.json\"))\n ) {\n errors[ERRORS.MISSING_DIR_OR_EMPTY_PROJECT] = true;\n return {\n errors,\n projectInfo: null,\n };\n }\n\n return {\n errors,\n projectInfo: null,\n };\n}\n","interface RegistryContext {\n headers: Record<string, Record<string, string>>;\n}\n\nlet context: RegistryContext = {\n headers: {},\n};\n\nexport function setRegistryHeaders(\n headers: Record<string, Record<string, string>>,\n) {\n // Merge new headers with existing ones to preserve headers for nested dependencies\n context.headers = { ...context.headers, ...headers };\n}\n\nexport function getRegistryHeadersFromContext(\n url: string,\n): Record<string, string> {\n return context.headers[url] || {};\n}\n\nexport function clearRegistryContext() {\n context.headers = {};\n}\n","import { detect } from \"@antfu/ni\";\n\nexport async function getPackageManager(\n targetDir: string,\n { withFallback }: { withFallback?: boolean } = {\n withFallback: false,\n },\n): Promise<\"yarn\" | \"pnpm\" | \"bun\" | \"npm\" | \"deno\"> {\n const packageManager = await detect({ programmatic: true, cwd: targetDir });\n\n if (packageManager === \"yarn@berry\") return \"yarn\";\n if (packageManager === \"pnpm@6\") return \"pnpm\";\n if (packageManager === \"bun\") return \"bun\";\n if (packageManager === \"deno\") return \"deno\";\n if (!withFallback) {\n return packageManager ?? \"npm\";\n }\n\n // Fallback to user agent if not detected.\n const userAgent = process.env.npm_config_user_agent || \"\";\n\n if (userAgent.startsWith(\"yarn\")) {\n return \"yarn\";\n }\n\n if (userAgent.startsWith(\"pnpm\")) {\n return \"pnpm\";\n }\n\n if (userAgent.startsWith(\"bun\")) {\n return \"bun\";\n }\n\n return \"npm\";\n}\n\nexport async function getPackageRunner(cwd: string) {\n const packageManager = await getPackageManager(cwd);\n\n if (packageManager === \"pnpm\") return \"pnpm dlx\";\n\n if (packageManager === \"bun\") return \"bunx\";\n\n return \"npx\";\n}\n","import { z } from \"zod\";\n\n// Error codes for programmatic error handling\nexport const RegistryErrorCode = {\n // Network errors\n NETWORK_ERROR: \"NETWORK_ERROR\",\n NOT_FOUND: \"NOT_FOUND\",\n UNAUTHORIZED: \"UNAUTHORIZED\",\n FORBIDDEN: \"FORBIDDEN\",\n FETCH_ERROR: \"FETCH_ERROR\",\n\n // Configuration errors\n NOT_CONFIGURED: \"NOT_CONFIGURED\",\n INVALID_CONFIG: \"INVALID_CONFIG\",\n MISSING_ENV_VARS: \"MISSING_ENV_VARS\",\n\n // File system errors\n LOCAL_FILE_ERROR: \"LOCAL_FILE_ERROR\",\n\n // Parsing errors\n PARSE_ERROR: \"PARSE_ERROR\",\n VALIDATION_ERROR: \"VALIDATION_ERROR\",\n\n // Generic errors\n UNKNOWN_ERROR: \"UNKNOWN_ERROR\",\n} as const;\n\nexport type RegistryErrorCode =\n (typeof RegistryErrorCode)[keyof typeof RegistryErrorCode];\n\nexport class RegistryError extends Error {\n public readonly code: RegistryErrorCode;\n public readonly statusCode?: number;\n public readonly context?: Record<string, unknown>;\n public readonly suggestion?: string;\n public readonly timestamp: Date;\n public readonly cause?: unknown;\n\n constructor(\n message: string,\n options: {\n code?: RegistryErrorCode;\n statusCode?: number;\n cause?: unknown;\n context?: Record<string, unknown>;\n suggestion?: string;\n } = {},\n ) {\n super(message);\n this.name = \"RegistryError\";\n this.code = options.code || RegistryErrorCode.UNKNOWN_ERROR;\n this.statusCode = options.statusCode;\n this.cause = options.cause;\n this.context = options.context;\n this.suggestion = options.suggestion;\n this.timestamp = new Date();\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n\n toJSON() {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n statusCode: this.statusCode,\n context: this.context,\n suggestion: this.suggestion,\n timestamp: this.timestamp,\n stack: this.stack,\n };\n }\n}\n\nexport class RegistryNotFoundError extends RegistryError {\n constructor(\n public readonly url: string,\n cause?: unknown,\n ) {\n const message = `The item at ${url} was not found. It may not exist at the registry.`;\n\n super(message, {\n code: RegistryErrorCode.NOT_FOUND,\n statusCode: 404,\n cause,\n context: { url },\n suggestion:\n \"Check if the item name is correct and the registry URL is accessible.\",\n });\n this.name = \"RegistryNotFoundError\";\n }\n}\n\nexport class RegistryUnauthorizedError extends RegistryError {\n constructor(\n public readonly url: string,\n cause?: unknown,\n ) {\n const message = `You are not authorized to access the item at ${url}. If this is a remote registry, you may need to authenticate.`;\n\n super(message, {\n code: RegistryErrorCode.UNAUTHORIZED,\n statusCode: 401,\n cause,\n context: { url },\n suggestion:\n \"Check your authentication credentials and environment variables.\",\n });\n this.name = \"RegistryUnauthorizedError\";\n }\n}\n\nexport class RegistryForbiddenError extends RegistryError {\n constructor(\n public readonly url: string,\n cause?: unknown,\n ) {\n const message = `You are not authorized to access the item at ${url}. If this is a remote registry, you may need to authenticate.`;\n\n super(message, {\n code: RegistryErrorCode.FORBIDDEN,\n statusCode: 403,\n cause,\n context: { url },\n suggestion:\n \"Check your authentication credentials and environment variables.\",\n });\n this.name = \"RegistryForbiddenError\";\n }\n}\n\nexport class RegistryFetchError extends RegistryError {\n constructor(\n public readonly url: string,\n statusCode?: number,\n public readonly responseBody?: string,\n cause?: unknown,\n ) {\n // Use the error detail from the server if available\n const baseMessage = statusCode\n ? `Failed to fetch from registry (${statusCode}): ${url}`\n : `Failed to fetch from registry: ${url}`;\n\n const message =\n typeof cause === \"string\" && cause\n ? `${baseMessage} - ${cause}`\n : baseMessage;\n\n let suggestion = \"Check your network connection and try again.\";\n if (statusCode === 404) {\n suggestion =\n \"The requested resource was not found. Check the URL or item name.\";\n } else if (statusCode === 500) {\n suggestion = \"The registry server encountered an error. Try again later.\";\n } else if (statusCode && statusCode >= 400 && statusCode < 500) {\n suggestion = \"There was a client error. Check your request parameters.\";\n }\n\n super(message, {\n code: RegistryErrorCode.FETCH_ERROR,\n statusCode,\n cause,\n context: { url, responseBody },\n suggestion,\n });\n this.name = \"RegistryFetchError\";\n }\n}\n\nexport class RegistryNotConfiguredError extends RegistryError {\n constructor(public readonly registryName: string | null) {\n const message = registryName\n ? `Unknown registry \"${registryName}\". Make sure it is defined in components.json as follows:\n{\n \"registries\": {\n \"${registryName}\": \"[URL_TO_REGISTRY]\"\n }\n}`\n : `Unknown registry. Make sure it is defined in components.json under \"registries\".`;\n\n super(message, {\n code: RegistryErrorCode.NOT_CONFIGURED,\n context: { registryName },\n suggestion:\n \"Add the registry configuration to your components.json file. Consult the registry documentation for the correct format.\",\n });\n this.name = \"RegistryNotConfiguredError\";\n }\n}\n\nexport class RegistryLocalFileError extends RegistryError {\n constructor(\n public readonly filePath: string,\n cause?: unknown,\n ) {\n super(`Failed to read local registry file: ${filePath}`, {\n code: RegistryErrorCode.LOCAL_FILE_ERROR,\n cause,\n context: { filePath },\n suggestion: \"Check if the file exists and you have read permissions.\",\n });\n this.name = \"RegistryLocalFileError\";\n }\n}\n\nexport class RegistryParseError extends RegistryError {\n public readonly parseError: unknown;\n\n constructor(\n public readonly item: string,\n parseError: unknown,\n ) {\n let message = `Failed to parse registry item: ${item}`;\n\n if (parseError instanceof z.ZodError) {\n message = `Failed to parse registry item: ${item}\\n${parseError.errors\n .map((e) => ` - ${e.path.join(\".\")}: ${e.message}`)\n .join(\"\\n\")}`;\n }\n\n super(message, {\n code: RegistryErrorCode.PARSE_ERROR,\n cause: parseError,\n context: { item },\n suggestion:\n \"The registry item may be corrupted or have an invalid format. Please make sure it returns a valid JSON object. See https://ui.shadcn.com/schema/registry-item.json.\",\n });\n\n this.parseError = parseError;\n this.name = \"RegistryParseError\";\n }\n}\n\nexport class RegistryMissingEnvironmentVariablesError extends RegistryError {\n constructor(\n public readonly registryName: string,\n public readonly missingVars: string[],\n ) {\n const message =\n `Registry \"${registryName}\" requires the following environment variables:\\n\\n` +\n missingVars.map((v) => ` • ${v}`).join(\"\\n\");\n\n super(message, {\n code: RegistryErrorCode.MISSING_ENV_VARS,\n context: { registryName, missingVars },\n suggestion:\n \"Set the required environment variables to your .env or .env.local file.\",\n });\n this.name = \"RegistryMissingEnvironmentVariablesError\";\n }\n}\n\nexport class RegistryInvalidNamespaceError extends RegistryError {\n constructor(public readonly name: string) {\n const message = `Invalid registry namespace: \"${name}\". Registry names must start with @ (e.g., @shadcn, @v0).`;\n\n super(message, {\n code: RegistryErrorCode.VALIDATION_ERROR,\n context: { name },\n suggestion:\n \"Use a valid registry name starting with @ or provide a direct URL to the registry.\",\n });\n this.name = \"RegistryInvalidNamespaceError\";\n }\n}\n\nexport class ConfigMissingError extends RegistryError {\n constructor(public readonly cwd: string) {\n const message = `No components.json found in ${cwd} or parent directories.`;\n\n super(message, {\n code: RegistryErrorCode.NOT_CONFIGURED,\n context: { cwd },\n suggestion:\n \"Run 'npx shadcn@latest init' to create a components.json file, or check that you're in the correct directory.\",\n });\n this.name = \"ConfigMissingError\";\n }\n}\n\nexport class ConfigParseError extends RegistryError {\n constructor(\n public readonly cwd: string,\n parseError: unknown,\n ) {\n let message = `Invalid components.json configuration in ${cwd}.`;\n\n if (parseError instanceof z.ZodError) {\n message = `Invalid components.json configuration in ${cwd}:\\n${parseError.errors\n .map((e) => ` - ${e.path.join(\".\")}: ${e.message}`)\n .join(\"\\n\")}`;\n }\n\n super(message, {\n code: RegistryErrorCode.INVALID_CONFIG,\n cause: parseError,\n context: { cwd },\n suggestion:\n \"Check your components.json file for syntax errors or invalid configuration. Run 'npx shadcn@latest init' to regenerate a valid configuration.\",\n });\n this.name = \"ConfigParseError\";\n }\n}\n","import { RegistryError } from \"@/src/registry/errors\";\nimport { highlighter } from \"@/src/utils/highlighter\";\nimport { logger } from \"@/src/utils/logger\";\nimport { z } from \"zod\";\n\nexport function handleError(error: unknown) {\n logger.break();\n logger.error(\n `Something went wrong. Please check the error below for more details.`,\n );\n logger.error(\n `If the problem persists, please open an issue on GitHub: https://github.com/bejamas/ui/issues`,\n );\n logger.error(\"\");\n if (typeof error === \"string\") {\n logger.error(error);\n logger.break();\n process.exit(1);\n }\n\n if (error instanceof RegistryError) {\n if (error.message) {\n logger.error(error.cause ? \"Error:\" : \"Message:\");\n logger.error(error.message);\n }\n\n if (error.cause) {\n logger.error(\"\\nMessage:\");\n logger.error(error.cause);\n }\n\n if (error.suggestion) {\n logger.error(\"\\nSuggestion:\");\n logger.error(error.suggestion);\n }\n logger.break();\n process.exit(1);\n }\n\n if (error instanceof z.ZodError) {\n logger.error(\"Validation failed:\");\n for (const [key, value] of Object.entries(error.flatten().fieldErrors)) {\n logger.error(`- ${highlighter.info(key)}: ${value}`);\n }\n logger.break();\n process.exit(1);\n }\n\n if (error instanceof Error) {\n logger.error(error.message);\n logger.break();\n process.exit(1);\n }\n\n logger.break();\n process.exit(1);\n}\n","import os from \"os\";\nimport path from \"path\";\nimport dotenv from \"dotenv\";\nimport { initOptionsSchema } from \"@/src/commands/init\";\nimport { getPackageManager } from \"@/src/utils/get-package-manager\";\nimport { handleError } from \"@/src/utils/handle-error\";\nimport { highlighter } from \"@/src/utils/highlighter\";\nimport { logger } from \"@/src/utils/logger\";\nimport { spinner } from \"@/src/utils/spinner\";\nimport { execa } from \"execa\";\nimport fs from \"fs-extra\";\nimport prompts from \"prompts\";\nimport { z } from \"zod\";\n\nexport const TEMPLATES = {\n astro: \"astro\",\n \"astro-monorepo\": \"astro-monorepo\",\n \"astro-with-component-docs-monorepo\": \"astro-with-component-docs-monorepo\",\n} as const;\n\nconst MONOREPO_TEMPLATE_URL =\n \"https://codeload.github.com/bejamas/ui/tar.gz/main\";\n\nexport async function createProject(\n options: Pick<\n z.infer<typeof initOptionsSchema>,\n \"cwd\" | \"force\" | \"srcDir\" | \"components\" | \"template\"\n >,\n) {\n options = {\n srcDir: false,\n ...options,\n };\n\n let template: keyof typeof TEMPLATES =\n options.template && TEMPLATES[options.template as keyof typeof TEMPLATES]\n ? (options.template as keyof typeof TEMPLATES)\n : \"astro\";\n\n let projectName: string = \"my-app\";\n\n const isRemoteComponent =\n options.components?.length === 1 &&\n !!options.components[0].match(/\\/chat\\/b\\//);\n\n if (!options.force) {\n const { type, name } = await prompts([\n {\n type: options.template || isRemoteComponent ? null : \"select\",\n name: \"type\",\n message: `The path ${highlighter.info(\n options.cwd,\n )} does not contain a package.json file.\\n Would you like to start a new project?`,\n choices: [\n { title: \"Astro\", value: \"astro\" },\n { title: \"Astro (Monorepo)\", value: \"astro-monorepo\" },\n {\n title: \"Astro with Component Docs (Monorepo)\",\n value: \"astro-with-component-docs-monorepo\",\n },\n ],\n initial: 0,\n },\n {\n type: \"text\",\n name: \"name\",\n message: \"What is your project named?\",\n initial: (_prev: any, values: any) => {\n const selectedTemplate: string =\n (options.template &&\n TEMPLATES[options.template as keyof typeof TEMPLATES] &&\n options.template) ||\n values.type ||\n template;\n return selectedTemplate?.endsWith(\"monorepo\")\n ? \"my-monorepo\"\n : \"my-app\";\n },\n format: (value: string) => value.trim(),\n validate: (value: string) =>\n value.length > 128\n ? `Name should be less than 128 characters.`\n : true,\n },\n ]);\n\n template = type ?? template;\n projectName = name;\n }\n\n const packageManager = await getPackageManager(options.cwd, {\n withFallback: true,\n });\n\n const projectPath = `${options.cwd}/${projectName}`;\n\n // Check if path is writable.\n try {\n await fs.access(options.cwd, fs.constants.W_OK);\n } catch (error) {\n logger.break();\n logger.error(`The path ${highlighter.info(options.cwd)} is not writable.`);\n logger.error(\n `It is likely you do not have write permissions for this folder or the path ${highlighter.info(\n options.cwd,\n )} does not exist.`,\n );\n logger.break();\n process.exit(1);\n }\n\n if (fs.existsSync(path.resolve(options.cwd, projectName, \"package.json\"))) {\n logger.break();\n logger.error(\n `A project with the name ${highlighter.info(projectName)} already exists.`,\n );\n logger.error(`Please choose a different name and try again.`);\n logger.break();\n process.exit(1);\n }\n\n await createProjectFromTemplate(projectPath, {\n templateKey: template,\n packageManager,\n cwd: options.cwd,\n });\n\n return {\n projectPath,\n projectName,\n template,\n };\n}\n\nasync function createProjectFromTemplate(\n projectPath: string,\n options: {\n templateKey: keyof typeof TEMPLATES;\n packageManager: string;\n cwd: string;\n },\n) {\n const createSpinner = spinner(\n `Creating a new project from template. This may take a few minutes.`,\n ).start();\n\n const TEMPLATE_TAR_SUBPATH: Record<keyof typeof TEMPLATES, string> = {\n astro: \"ui-main/templates/astro\",\n \"astro-monorepo\": \"ui-main/templates/monorepo-astro\",\n \"astro-with-component-docs-monorepo\":\n \"ui-main/templates/monorepo-astro-with-docs\",\n };\n\n try {\n // Load local .env if present to allow GITHUB_TOKEN/GH_TOKEN\n dotenv.config({ quiet: true });\n const templatePath = path.join(\n os.tmpdir(),\n `bejamas-template-${Date.now()}`,\n );\n await fs.ensureDir(templatePath);\n\n // Auth via environment variables (.env supported)\n const authToken = process.env.GITHUB_TOKEN || process.env.GH_TOKEN;\n const usedAuth = Boolean(authToken);\n const headers: Record<string, string> = {\n \"User-Agent\": \"bejamas-cli\",\n };\n if (authToken) {\n headers[\"Authorization\"] = `Bearer ${authToken}`;\n }\n\n const response = await fetch(MONOREPO_TEMPLATE_URL, { headers });\n if (!response.ok) {\n if (\n response.status === 401 ||\n response.status === 403 ||\n (!usedAuth && response.status === 404)\n ) {\n throw new Error(\n \"Unauthorized to access private template. Set GITHUB_TOKEN or GH_TOKEN (in .env or env) with repo access and try again.\",\n );\n }\n if (response.status === 404) {\n throw new Error(\"Failed to download template: not found.\");\n }\n throw new Error(\n `Failed to download template: ${response.status} ${response.statusText}`,\n );\n }\n\n const tarPath = path.resolve(templatePath, \"template.tar.gz\");\n await fs.writeFile(tarPath, Buffer.from(await response.arrayBuffer()));\n\n const tarSubpath = TEMPLATE_TAR_SUBPATH[options.templateKey];\n const leafName = tarSubpath.split(\"/\").pop() as string;\n\n await execa(\"tar\", [\n \"-xzf\",\n tarPath,\n \"-C\",\n templatePath,\n \"--strip-components=2\",\n tarSubpath,\n ]);\n\n const extractedPath = path.resolve(templatePath, leafName);\n await fs.move(extractedPath, projectPath);\n await fs.remove(templatePath);\n\n await execa(options.packageManager, [\"install\"], {\n cwd: projectPath,\n });\n\n try {\n // Detect if we're inside an existing git repo; if yes, skip initializing a nested repo\n const { stdout } = await execa(\n \"git\",\n [\"rev-parse\", \"--is-inside-work-tree\"],\n { cwd: projectPath },\n );\n const insideExistingRepo = stdout.trim() === \"true\";\n\n if (!insideExistingRepo) {\n await execa(\"git\", [\"init\"], { cwd: projectPath });\n await execa(\"git\", [\"add\", \"-A\"], { cwd: projectPath });\n await execa(\"git\", [\"commit\", \"-m\", \"Initial commit\"], {\n cwd: projectPath,\n });\n }\n } catch (_) {\n // ignore git detection/initialization failures\n }\n\n createSpinner?.succeed(\"Creating a new project from template.\");\n } catch (error) {\n createSpinner?.fail(\n \"Something went wrong creating a new project from template.\",\n );\n handleError(error);\n }\n}\n","import { promises as fs } from \"fs\";\nimport path from \"path\";\nimport { preFlightInit } from \"@/src/preflights/preflight-init\";\n\nimport { BASE_COLORS, BUILTIN_REGISTRIES } from \"@/src/registry/constants\";\nimport { clearRegistryContext } from \"@/src/registry/context\";\n\nimport { TEMPLATES, createProject } from \"@/src/utils/create-project\";\nimport * as ERRORS from \"@/src/utils/errors\";\nimport { getConfig, createConfig, type Config } from \"@/src/utils/get-config\";\nimport { getProjectConfig, getProjectInfo } from \"@/src/utils/get-project-info\";\nimport { getPackageRunner } from \"@/src/utils/get-package-manager\";\nimport { handleError } from \"@/src/utils/handle-error\";\nimport { highlighter } from \"@/src/utils/highlighter\";\nimport { logger } from \"@/src/utils/logger\";\nimport { Command } from \"commander\";\nimport { execa } from \"execa\";\nimport fsExtra from \"fs-extra\";\nimport { z } from \"zod\";\n\n// process.on(\"exit\", (code) => {\n// const filePath = path.resolve(process.cwd(), \"components.json\")\n\n// // Delete backup if successful.\n// if (code === 0) {\n// return deleteFileBackup(filePath)\n// }\n\n// // Restore backup if error.\n// return restoreFileBackup(filePath)\n// })\n\n// Default fallback registry endpoint for shadcn (expects /r)\nconst DEFAULT_REGISTRY_URL = \"https://ui.bejamas.com/r\";\n\nexport const initOptionsSchema = z.object({\n cwd: z.string(),\n components: z.array(z.string()).optional(),\n yes: z.boolean(),\n defaults: z.boolean(),\n force: z.boolean(),\n silent: z.boolean(),\n isNewProject: z.boolean(),\n srcDir: z.boolean().optional(),\n cssVariables: z.boolean(),\n template: z\n .string()\n .optional()\n .refine(\n (val) => {\n if (val) {\n return TEMPLATES[val as keyof typeof TEMPLATES];\n }\n return true;\n },\n {\n message: \"Invalid template. Please use 'next' or 'next-monorepo'.\",\n },\n ),\n baseColor: z\n .string()\n .optional()\n .refine(\n (val) => {\n if (val) {\n return BASE_COLORS.find((color) => color.name === val);\n }\n\n return true;\n },\n {\n message: `Invalid base color. Please use '${BASE_COLORS.map(\n (color) => color.name,\n ).join(\"', '\")}'`,\n },\n ),\n baseStyle: z.boolean(),\n});\n\nexport const init = new Command()\n .name(\"init\")\n .description(\"initialize your project and install dependencies\")\n .argument(\"[components...]\", \"names, url or local path to component\")\n .option(\n \"-t, --template <template>\",\n \"the template to use. (next, next-monorepo)\",\n )\n .option(\n \"-b, --base-color <base-color>\",\n \"the base color to use. (neutral, gray, zinc, stone, slate)\",\n undefined,\n )\n .option(\"-y, --yes\", \"skip confirmation prompt.\", true)\n .option(\"-d, --defaults,\", \"use default configuration.\", false)\n .option(\"-f, --force\", \"force overwrite of existing configuration.\", false)\n .option(\n \"-c, --cwd <cwd>\",\n \"the working directory. defaults to the current directory.\",\n process.cwd(),\n )\n .option(\"-s, --silent\", \"mute output.\", false)\n .option(\n \"--src-dir\",\n \"use the src directory when creating a new project.\",\n false,\n )\n .option(\n \"--no-src-dir\",\n \"do not use the src directory when creating a new project.\",\n )\n .option(\"--css-variables\", \"use css variables for theming.\", true)\n .option(\"--no-css-variables\", \"do not use css variables for theming.\")\n .option(\"--no-base-style\", \"do not install the base shadcn style.\")\n .action(async (_components, opts) => {\n try {\n await runInit(opts);\n } catch (error) {\n logger.break();\n handleError(error);\n } finally {\n clearRegistryContext();\n }\n });\n\nexport async function runInit(\n options: z.infer<typeof initOptionsSchema> & {\n skipPreflight?: boolean;\n },\n) {\n let projectInfo;\n let newProjectTemplate;\n if (!options.skipPreflight) {\n const preflight = await preFlightInit(options);\n\n if (preflight.errors[ERRORS.MISSING_DIR_OR_EMPTY_PROJECT]) {\n const { projectPath, template } = await createProject(options);\n if (!projectPath) {\n process.exit(1);\n }\n options.cwd = projectPath;\n options.isNewProject = true;\n newProjectTemplate = template;\n }\n projectInfo = preflight.projectInfo;\n } else {\n projectInfo = await getProjectInfo(options.cwd);\n }\n\n if (newProjectTemplate) {\n const projectPath = {\n \"astro-monorepo\": \"apps/web\",\n \"astro-with-component-docs-monorepo\": \"apps/web\",\n astro: \"\",\n } as const;\n options.cwd = path.resolve(options.cwd, projectPath[newProjectTemplate]);\n\n logger.log(\n `${highlighter.success(\n \"Success!\",\n )} Project initialization completed.\\nYou may now add components.`,\n );\n\n return await getConfig(options.cwd);\n }\n\n // const projectConfig = await getProjectConfig(options.cwd, projectInfo);\n\n const shadcnBin = process.platform === \"win32\" ? \"shadcn.cmd\" : \"shadcn\";\n const localShadcnPath = path.resolve(\n options.cwd,\n \"node_modules\",\n \".bin\",\n shadcnBin,\n );\n\n try {\n const env = {\n ...process.env,\n REGISTRY_URL: process.env.REGISTRY_URL || DEFAULT_REGISTRY_URL,\n };\n if (await fsExtra.pathExists(localShadcnPath)) {\n await execa(localShadcnPath, [\"init\", \"--base-color\", \"neutral\"], {\n stdio: \"inherit\",\n cwd: options.cwd,\n env,\n });\n } else {\n // Follow user's runner preference (npx, bunx, pnpm dlx)\n await execa(\n \"npx\",\n [\"-y\", \"shadcn@latest\", \"init\", \"--base-color\", \"neutral\"],\n {\n stdio: \"inherit\",\n cwd: options.cwd,\n env,\n },\n );\n }\n } catch (err) {\n // shadcn already printed the detailed error to stdio, avoid double-reporting\n process.exit(1);\n }\n}\n","import { resolve } from \"node:path\";\nimport { existsSync, readFileSync } from \"node:fs\";\n\n/**\n * Read and parse tsconfig.json from the project root\n */\nexport function readTsConfig(projectRoot: string): any | null {\n try {\n const tsconfigPath = resolve(projectRoot, \"tsconfig.json\");\n if (!existsSync(tsconfigPath)) return null;\n const raw = readFileSync(tsconfigPath, \"utf-8\");\n return JSON.parse(raw);\n } catch {\n return null;\n }\n}\n\n/**\n * Resolve an alias path (like @/components) using tsconfig.json paths\n */\nexport function resolveAliasPathUsingTsConfig(\n inputPath: string,\n projectRoot: string,\n): string | null {\n const cfg = readTsConfig(projectRoot);\n if (!cfg || !cfg.compilerOptions) return null;\n const baseUrl: string = cfg.compilerOptions.baseUrl || \".\";\n const paths: Record<string, string[] | string> =\n cfg.compilerOptions.paths || {};\n for (const [key, values] of Object.entries(paths)) {\n const pattern = key.replace(/\\*/g, \"(.*)\");\n const re = new RegExp(`^${pattern}$`);\n const match = inputPath.match(re);\n if (!match) continue;\n const wildcard = match[1] || \"\";\n const first = Array.isArray(values) ? values[0] : values;\n if (!first) continue;\n const target = String(first).replace(/\\*/g, wildcard);\n return resolve(projectRoot, baseUrl, target);\n }\n return null;\n}\n","import { Command } from \"commander\";\nimport { resolve, isAbsolute, relative } from \"node:path\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { logger } from \"@/src/utils/logger\";\nimport { resolveAliasPathUsingTsConfig } from \"@/src/utils/tsconfig-utils\";\nimport prompts from \"prompts\";\n\nasync function generateDocs({\n cwd,\n outDir,\n verbose,\n}: {\n cwd?: string;\n outDir?: string;\n verbose?: boolean;\n}) {\n const DEBUG =\n process.env.BEJAMAS_DEBUG === \"1\" ||\n process.env.BEJAMAS_DEBUG === \"true\" ||\n verbose;\n\n try {\n const shellCwd = process.cwd();\n\n // Probe for components.json up the directory tree starting from shell CWD\n let projectRoot = shellCwd;\n let probe: string | null = shellCwd;\n for (let i = 0; i < 6 && probe; i += 1) {\n const candidate = resolve(probe, \"components.json\");\n if (existsSync(candidate)) {\n projectRoot = probe;\n try {\n const raw = readFileSync(candidate, \"utf-8\");\n const config = JSON.parse(raw);\n // If UI root not provided via CLI, try to infer from aliases.ui first\n if (!cwd && !process.env.BEJAMAS_UI_ROOT && config?.aliases?.ui) {\n const mapped: string = String(config.aliases.ui);\n let uiAbs: string | null = null;\n if (\n mapped.startsWith(\"./\") ||\n mapped.startsWith(\"../\") ||\n isAbsolute(mapped)\n ) {\n uiAbs = resolve(projectRoot, mapped);\n } else {\n uiAbs = resolveAliasPathUsingTsConfig(mapped, projectRoot);\n }\n if (!uiAbs && mapped.startsWith(\"@/\")) {\n uiAbs = resolve(projectRoot, \"src\", mapped.slice(2));\n }\n if (uiAbs) {\n process.env.BEJAMAS_UI_ROOT = uiAbs;\n }\n }\n // Fallback: infer UI root from tailwind.css\n if (!cwd && !process.env.BEJAMAS_UI_ROOT && config?.tailwind?.css) {\n const cssRaw = String(config.tailwind.css);\n let cssAbs: string | null = null;\n if (\n cssRaw.startsWith(\"./\") ||\n cssRaw.startsWith(\"../\") ||\n isAbsolute(cssRaw)\n ) {\n cssAbs = resolve(projectRoot, cssRaw);\n } else {\n cssAbs = resolveAliasPathUsingTsConfig(cssRaw, projectRoot);\n }\n if (!cssAbs && cssRaw.startsWith(\"@/\")) {\n cssAbs = resolve(projectRoot, \"src\", cssRaw.slice(2));\n }\n if (cssAbs) {\n const uiRootFromCss = resolve(cssAbs, \"..\", \"..\", \"..\");\n process.env.BEJAMAS_UI_ROOT = uiRootFromCss;\n }\n }\n // If out dir not provided via CLI, try to infer from aliases.docs\n if (!outDir && config?.aliases?.docs) {\n const mapped: string = String(config.aliases.docs);\n let outResolved: string | null = null;\n if (\n mapped.startsWith(\"./\") ||\n mapped.startsWith(\"../\") ||\n isAbsolute(mapped)\n ) {\n outResolved = mapped;\n } else {\n const abs = resolveAliasPathUsingTsConfig(mapped, projectRoot);\n if (abs) outResolved = relative(projectRoot, abs);\n }\n if (!outResolved && mapped.startsWith(\"@/\")) {\n outResolved = mapped.replace(/^@\\//, \"src/\");\n }\n // As a last resort, use the mapped value as-is so we do not prompt for output\n const finalOut = outResolved ?? mapped;\n if (finalOut && !process.env.BEJAMAS_DOCS_OUT_DIR) {\n process.env.BEJAMAS_DOCS_OUT_DIR = finalOut;\n process.env.BEJAMAS_DOCS_CWD = projectRoot;\n }\n }\n } catch {}\n break;\n }\n const parent = resolve(probe, \"..\");\n probe = parent === probe ? null : parent;\n }\n\n // Defaults if not already set from components.json\n if (!process.env.BEJAMAS_DOCS_CWD) {\n process.env.BEJAMAS_DOCS_CWD = shellCwd;\n }\n if (!process.env.BEJAMAS_UI_ROOT) {\n // Ask user for @bejamas/ui root when not inferred\n const defaultGuess = (() => {\n // Try local monorepo style packages/ui\n let current = shellCwd;\n for (let i = 0; i < 6; i += 1) {\n const cand = resolve(current, \"packages/ui/package.json\");\n if (existsSync(cand)) {\n const abs = resolve(current, \"packages/ui\");\n const rel = relative(shellCwd, abs);\n return rel || abs;\n }\n const parent = resolve(current, \"..\");\n if (parent === current) break;\n current = parent;\n }\n // Try installed node_modules fallback\n const nm = resolve(shellCwd, \"node_modules/@bejamas/ui/package.json\");\n if (existsSync(nm)) {\n const abs = resolve(shellCwd, \"node_modules/@bejamas/ui\");\n const rel = relative(shellCwd, abs);\n return rel || abs;\n }\n // Last resort: suggest a common local path\n return \"packages/ui\";\n })();\n const { uiRoot } = await prompts({\n type: \"text\",\n name: \"uiRoot\",\n message: \"Path to @bejamas/ui package root:\",\n initial: defaultGuess,\n validate: (val: string) => {\n const p = resolve(shellCwd, val);\n return existsSync(resolve(p, \"package.json\"))\n ? true\n : `No package.json found in ${p}`;\n },\n });\n if (!uiRoot) {\n logger.error(\"@bejamas/ui root is required to generate docs.\");\n process.exit(1);\n }\n process.env.BEJAMAS_UI_ROOT = resolve(shellCwd, uiRoot);\n }\n\n // CLI overrides take precedence\n if (cwd && cwd.length) {\n process.env.BEJAMAS_UI_ROOT = resolve(cwd);\n }\n if (outDir && outDir.length) {\n // Pass through exactly as provided; the generator will resolve against BEJAMAS_DOCS_CWD if needed.\n process.env.BEJAMAS_DOCS_OUT_DIR = outDir;\n }\n\n // If output dir still not defined, prompt the user\n if (!process.env.BEJAMAS_DOCS_OUT_DIR) {\n const { out } = await prompts({\n type: \"text\",\n name: \"out\",\n message: \"Where should we output docs (relative to project root)?\",\n initial: \"src/content/docs/components\",\n });\n if (!out) {\n logger.error(\"An output directory is required to generate docs.\");\n process.exit(1);\n }\n process.env.BEJAMAS_DOCS_OUT_DIR = out;\n process.env.BEJAMAS_DOCS_CWD = process.env.BEJAMAS_DOCS_CWD || shellCwd;\n }\n // Ensure the generator does not auto-run upon import; we'll invoke it explicitly\n process.env.BEJAMAS_SKIP_AUTO_RUN = \"1\";\n logger.info(`Generating docs...`);\n if (DEBUG) {\n logger.info(`Generator entry: @/src/docs/generate-mdx/index`);\n if (process.env.BEJAMAS_UI_ROOT)\n logger.info(`UI root: ${process.env.BEJAMAS_UI_ROOT}`);\n if (process.env.BEJAMAS_DOCS_CWD)\n logger.info(`Docs CWD: ${process.env.BEJAMAS_DOCS_CWD}`);\n if (process.env.BEJAMAS_DOCS_OUT_DIR)\n logger.info(`Docs out: ${process.env.BEJAMAS_DOCS_OUT_DIR}`);\n }\n const mod = await import(\"@/src/docs/generate-mdx/index\");\n if (typeof mod.runDocsGenerator === \"function\") {\n await mod.runDocsGenerator();\n } else {\n throw new Error(\n \"Failed to load docs generator. Export 'runDocsGenerator' not found.\",\n );\n }\n } catch (err: any) {\n logger.error(err?.message || String(err));\n process.exit(1);\n }\n}\n\nexport const docs = new Command()\n .name(\"docs:build\")\n .alias(\"docs\")\n .description(\"generate docs from @bejamas/ui components\")\n .option(\"-c, --cwd <cwd>\", \"path to UI working directory\")\n .option(\"-o, --out <outDir>\", \"output directory for generated MDX files\")\n .action(async (opts) => {\n await generateDocs({\n cwd: opts.cwd,\n outDir: opts.out,\n verbose: Boolean(opts.verbose),\n });\n });\n","import { Command } from \"commander\";\nimport { resolve, isAbsolute, join, extname } from \"node:path\";\nimport { existsSync, readFileSync, readdirSync } from \"node:fs\";\nimport {\n cyan,\n green,\n red,\n yellow,\n dim,\n bold,\n magenta,\n white,\n} from \"kleur/colors\";\nimport { logger } from \"@/src/utils/logger\";\nimport { resolveAliasPathUsingTsConfig } from \"@/src/utils/tsconfig-utils\";\nimport {\n extractFrontmatter,\n parseJsDocMetadata,\n resolveUiRoot,\n} from \"@/src/docs/generate-mdx/utils\";\n\ninterface ComponentDocStatus {\n name: string;\n file: string;\n status: \"complete\" | \"incomplete\" | \"missing\";\n missingRequired: string[];\n missingRecommended: string[];\n}\n\ninterface CheckResult {\n total: number;\n complete: ComponentDocStatus[];\n incomplete: ComponentDocStatus[];\n missing: ComponentDocStatus[];\n}\n\nconst REQUIRED_FIELDS = [\"name\", \"title\", \"description\"] as const;\nconst RECOMMENDED_FIELDS = [\n \"primaryExampleMDX\",\n \"usageMDX\",\n \"figmaUrl\",\n] as const;\n\nconst FIELD_LABELS: Record<string, string> = {\n name: \"@component\",\n title: \"@title\",\n description: \"@description\",\n primaryExampleMDX: \"@preview\",\n usageMDX: \"@usage\",\n figmaUrl: \"@figmaUrl\",\n};\n\nfunction checkComponentDocs(\n filePath: string,\n fileName: string,\n): ComponentDocStatus {\n const content = readFileSync(filePath, \"utf-8\");\n const frontmatter = extractFrontmatter(content);\n const meta = parseJsDocMetadata(frontmatter);\n\n const componentName = fileName.replace(/\\.astro$/i, \"\");\n const missingRequired: string[] = [];\n const missingRecommended: string[] = [];\n\n for (const field of REQUIRED_FIELDS) {\n const value = meta[field];\n if (!value || (typeof value === \"string\" && !value.trim())) {\n missingRequired.push(FIELD_LABELS[field] || field);\n }\n }\n\n for (const field of RECOMMENDED_FIELDS) {\n const value = meta[field];\n if (!value || (typeof value === \"string\" && !value.trim())) {\n missingRecommended.push(FIELD_LABELS[field] || field);\n }\n }\n\n let status: \"complete\" | \"incomplete\" | \"missing\";\n if (missingRequired.length > 0) {\n status = \"missing\";\n } else if (missingRecommended.length > 0) {\n status = \"incomplete\";\n } else {\n status = \"complete\";\n }\n\n return {\n name: componentName,\n file: fileName,\n status,\n missingRequired,\n missingRecommended,\n };\n}\n\nasync function checkDocs({\n cwd,\n json,\n}: {\n cwd?: string;\n json?: boolean;\n}): Promise<void> {\n try {\n const shellCwd = process.cwd();\n\n // Probe for components.json up the directory tree starting from shell CWD\n let projectRoot = shellCwd;\n let probe: string | null = shellCwd;\n for (let i = 0; i < 6 && probe; i += 1) {\n const candidate = resolve(probe, \"components.json\");\n if (existsSync(candidate)) {\n projectRoot = probe;\n try {\n const raw = readFileSync(candidate, \"utf-8\");\n const config = JSON.parse(raw);\n // If UI root not provided via CLI, try to infer from aliases.ui first\n if (!cwd && !process.env.BEJAMAS_UI_ROOT && config?.aliases?.ui) {\n const mapped: string = String(config.aliases.ui);\n let uiAbs: string | null = null;\n if (\n mapped.startsWith(\"./\") ||\n mapped.startsWith(\"../\") ||\n isAbsolute(mapped)\n ) {\n uiAbs = resolve(projectRoot, mapped);\n } else {\n uiAbs = resolveAliasPathUsingTsConfig(mapped, projectRoot);\n }\n if (!uiAbs && mapped.startsWith(\"@/\")) {\n uiAbs = resolve(projectRoot, \"src\", mapped.slice(2));\n }\n if (uiAbs) {\n process.env.BEJAMAS_UI_ROOT = uiAbs;\n }\n }\n // Fallback: infer UI root from tailwind.css\n if (!cwd && !process.env.BEJAMAS_UI_ROOT && config?.tailwind?.css) {\n const cssRaw = String(config.tailwind.css);\n let cssAbs: string | null = null;\n if (\n cssRaw.startsWith(\"./\") ||\n cssRaw.startsWith(\"../\") ||\n isAbsolute(cssRaw)\n ) {\n cssAbs = resolve(projectRoot, cssRaw);\n } else {\n cssAbs = resolveAliasPathUsingTsConfig(cssRaw, projectRoot);\n }\n if (!cssAbs && cssRaw.startsWith(\"@/\")) {\n cssAbs = resolve(projectRoot, \"src\", cssRaw.slice(2));\n }\n if (cssAbs) {\n const uiRootFromCss = resolve(cssAbs, \"..\", \"..\", \"..\");\n process.env.BEJAMAS_UI_ROOT = uiRootFromCss;\n }\n }\n } catch {}\n break;\n }\n const parent = resolve(probe, \"..\");\n probe = parent === probe ? null : parent;\n }\n\n // CLI override takes precedence\n if (cwd && cwd.length) {\n process.env.BEJAMAS_UI_ROOT = resolve(cwd);\n }\n\n let uiRoot: string;\n try {\n uiRoot = resolveUiRoot(shellCwd);\n } catch {\n logger.error(\n \"Unable to locate @bejamas/ui. Use --cwd to specify the UI package path.\",\n );\n process.exit(1);\n }\n\n const componentsDir = join(uiRoot, \"src\", \"components\");\n if (!existsSync(componentsDir)) {\n logger.error(\n `Components directory not found: ${componentsDir}\\n\\n` +\n `Expected structure: <uiRoot>/src/components/*.astro\\n` +\n `Use --cwd to specify a different UI package root.`,\n );\n process.exit(1);\n }\n\n const files = readdirSync(componentsDir, { withFileTypes: true })\n .filter((e) => e.isFile() && extname(e.name).toLowerCase() === \".astro\")\n .map((e) => e.name)\n .sort();\n\n if (files.length === 0) {\n logger.warn(\"No .astro component files found.\");\n process.exit(0);\n }\n\n const results: ComponentDocStatus[] = [];\n for (const file of files) {\n const filePath = join(componentsDir, file);\n const status = checkComponentDocs(filePath, file);\n results.push(status);\n }\n\n const complete = results.filter((r) => r.status === \"complete\");\n const incomplete = results.filter((r) => r.status === \"incomplete\");\n const missing = results.filter((r) => r.status === \"missing\");\n\n const checkResult: CheckResult = {\n total: results.length,\n complete,\n incomplete,\n missing,\n };\n\n if (json) {\n console.log(JSON.stringify(checkResult, null, 2));\n // Exit with error code if there are components missing required docs\n if (missing.length > 0) {\n process.exit(1);\n }\n return;\n }\n\n // Print formatted report\n const termWidth = Math.min(80, process.stdout.columns || 80);\n const headerLine = \"━\".repeat(termWidth);\n\n logger.break();\n console.log(dim(\"┌\" + \"─\".repeat(termWidth - 2) + \"┐\"));\n console.log(\n dim(\"│\") +\n bold(cyan(\" docs:check\")) +\n dim(\" — Component Documentation Status\") +\n \" \".repeat(Math.max(0, termWidth - 47)) +\n dim(\"│\"),\n );\n console.log(dim(\"└\" + \"─\".repeat(termWidth - 2) + \"┘\"));\n logger.break();\n\n // Helper to format tags with color\n const formatTag = (tag: string) => magenta(tag);\n const formatComponentName = (name: string) => bold(white(name));\n\n // Complete components\n if (complete.length > 0) {\n console.log(\n green(\n `✓ Complete (${complete.length} component${complete.length === 1 ? \"\" : \"s\"}):`,\n ),\n );\n const names = complete\n .map((c) => formatComponentName(c.name))\n .join(dim(\", \"));\n console.log(` ${names}`);\n logger.break();\n }\n\n // Incomplete components (missing recommended fields)\n if (incomplete.length > 0) {\n console.log(\n yellow(\n `⚠ Incomplete (${incomplete.length} component${incomplete.length === 1 ? \"\" : \"s\"}):`,\n ),\n );\n for (const comp of incomplete) {\n const missingFields = comp.missingRecommended\n .map(formatTag)\n .join(dim(\", \"));\n console.log(\n ` ${formatComponentName(comp.name)} ${dim(\"-\")} ${dim(\"missing:\")} ${missingFields}`,\n );\n }\n logger.break();\n }\n\n // Missing docs (missing required fields)\n if (missing.length > 0) {\n console.log(\n red(\n `✗ Missing Docs (${missing.length} component${missing.length === 1 ? \"\" : \"s\"}):`,\n ),\n );\n for (const comp of missing) {\n const missingFields = comp.missingRequired\n .map(formatTag)\n .join(dim(\", \"));\n console.log(\n ` ${formatComponentName(comp.name)} ${dim(\"-\")} ${dim(\"missing:\")} ${missingFields}`,\n );\n }\n logger.break();\n }\n\n // Summary\n console.log(dim(headerLine));\n const completeText = green(`${complete.length}/${results.length} complete`);\n const incompleteText =\n incomplete.length > 0\n ? yellow(`${incomplete.length} incomplete`)\n : dim(`${incomplete.length} incomplete`);\n const missingText =\n missing.length > 0\n ? red(`${missing.length} missing docs`)\n : dim(`${missing.length} missing docs`);\n console.log(\n `${bold(\"Summary:\")} ${completeText} ${dim(\"|\")} ${incompleteText} ${dim(\"|\")} ${missingText}`,\n );\n logger.break();\n\n // Exit with error code if there are components missing required docs\n if (missing.length > 0) {\n process.exit(1);\n }\n } catch (err: any) {\n logger.error(err?.message || String(err));\n process.exit(1);\n }\n}\n\nexport const docsCheck = new Command()\n .name(\"docs:check\")\n .description(\"check documentation status for all components\")\n .option(\"-c, --cwd <cwd>\", \"path to UI working directory\")\n .option(\"--json\", \"output results as JSON\")\n .action(async (opts) => {\n await checkDocs({\n cwd: opts.cwd,\n json: Boolean(opts.json),\n });\n });\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport fg from \"fast-glob\";\nimport { logger } from \"@/src/utils/logger\";\nimport { Config, getConfig } from \"@/src/utils/get-config\";\n\nexport function updateImportAliases(\n moduleSpecifier: string,\n config: Config,\n isRemote: boolean = false,\n) {\n // Not a local import.\n if (!moduleSpecifier.startsWith(\"@/\") && !isRemote) {\n return moduleSpecifier;\n }\n\n // This treats the remote as coming from a faux registry.\n let specifier = moduleSpecifier;\n if (isRemote && specifier.startsWith(\"@/\")) {\n specifier = specifier.replace(/^@\\//, \"@/registry/new-york/\");\n }\n\n // Not a registry import.\n if (!specifier.startsWith(\"@/registry/\")) {\n // We fix the alias and return.\n const alias = config.aliases.components.split(\"/\")[0];\n return specifier.replace(/^@\\//, `${alias}/`);\n }\n\n if (specifier.match(/^@\\/registry\\/(.+)\\/ui/)) {\n return specifier.replace(\n /^@\\/registry\\/(.+)\\/ui/,\n config.aliases.ui ?? `${config.aliases.components}/ui`,\n );\n }\n\n if (\n config.aliases.components &&\n specifier.match(/^@\\/registry\\/(.+)\\/components/)\n ) {\n return specifier.replace(\n /^@\\/registry\\/(.+)\\/components/,\n config.aliases.components,\n );\n }\n\n if (config.aliases.lib && specifier.match(/^@\\/registry\\/(.+)\\/lib/)) {\n return specifier.replace(/^@\\/registry\\/(.+)\\/lib/, config.aliases.lib);\n }\n\n if (config.aliases.hooks && specifier.match(/^@\\/registry\\/(.+)\\/hooks/)) {\n return specifier.replace(/^@\\/registry\\/(.+)\\/hooks/, config.aliases.hooks);\n }\n\n return specifier.replace(/^@\\/registry\\/[^/]+/, config.aliases.components);\n}\n\nexport function rewriteAstroImports(content: string, config: Config) {\n let updated = content;\n\n const utilsAlias = config.aliases?.utils;\n const workspaceAlias =\n typeof utilsAlias === \"string\" && utilsAlias.includes(\"/\")\n ? utilsAlias.split(\"/\")[0]\n : \"@\";\n const utilsImport = `${workspaceAlias}/lib/utils`;\n\n // Handle standard imports with specifiers, e.g. `import { x } from \"path\"`\n updated = updated.replace(\n /import\\s+([\\s\\S]*?)\\s+from\\s+[\"']([^\"']+)[\"']/g,\n (full, importsPart, specifier) => {\n const next = updateImportAliases(specifier, config, false);\n\n let finalSpec = next;\n const includesCn =\n typeof importsPart === \"string\" &&\n importsPart.split(/[{},\\s]/).some((part: string) => part === \"cn\");\n\n if (\n includesCn &&\n config.aliases.utils &&\n (next === utilsImport || next === \"@/lib/utils\")\n ) {\n finalSpec =\n utilsImport === next\n ? next.replace(utilsImport, config.aliases.utils)\n : config.aliases.utils;\n }\n\n if (finalSpec === specifier) return full;\n return full.replace(specifier, finalSpec);\n },\n );\n\n // Handle bare imports, e.g. `import \"path\"`\n updated = updated.replace(/import\\s+[\"']([^\"']+)[\"']/g, (full, specifier) => {\n const next = updateImportAliases(specifier, config, false);\n if (next === specifier) return full;\n return full.replace(specifier, next);\n });\n\n return updated;\n}\n\nexport async function fixAstroImports(cwd: string, isVerbose: boolean) {\n const config = await getConfig(cwd);\n if (!config) return;\n\n const searchRoots = new Set<string>([\n config.resolvedPaths.components,\n config.resolvedPaths.ui,\n ]);\n\n for (const root of Array.from(searchRoots)) {\n if (!root) continue;\n const astroFiles = await fg(\"**/*.astro\", {\n cwd: root,\n absolute: true,\n dot: false,\n });\n\n for (const filePath of astroFiles) {\n const original = await fs.readFile(filePath, \"utf8\");\n const rewritten = rewriteAstroImports(original, config);\n if (rewritten === original) continue;\n await fs.writeFile(filePath, rewritten, \"utf8\");\n if (isVerbose) {\n logger.info(\n `[bejamas-ui] fixed imports in ${path.relative(cwd, filePath)}`,\n );\n }\n }\n }\n}\n\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { logger } from \"@/src/utils/logger\";\n\nexport interface RegistryFile {\n path: string;\n content: string;\n type: string;\n target?: string;\n}\n\nexport interface RegistryItem {\n name: string;\n type: string;\n files: RegistryFile[];\n dependencies?: string[];\n devDependencies?: string[];\n registryDependencies?: string[];\n}\n\n/** Maps filename to subfolder/filename for path rewriting */\nexport type PathRewriteMap = Map<string, string>;\n\n/**\n * Fetches a registry item JSON from the registry URL.\n */\nexport async function fetchRegistryItem(\n componentName: string,\n registryUrl: string,\n): Promise<RegistryItem | null> {\n // Handle style-prefixed URLs (e.g., styles/new-york-v4/avatar.json)\n const url = `${registryUrl}/styles/new-york-v4/${componentName}.json`;\n\n try {\n const response = await fetch(url);\n if (!response.ok) {\n // Try without styles prefix as fallback\n const fallbackUrl = `${registryUrl}/${componentName}.json`;\n const fallbackResponse = await fetch(fallbackUrl);\n if (!fallbackResponse.ok) {\n return null;\n }\n return (await fallbackResponse.json()) as RegistryItem;\n }\n return (await response.json()) as RegistryItem;\n } catch {\n return null;\n }\n}\n\n/**\n * Extracts the subfolder name from registry file paths.\n * E.g., \"components/ui/avatar/Avatar.astro\" → \"avatar\"\n */\nexport function getSubfolderFromPaths(files: RegistryFile[]): string | null {\n // Only consider registry:ui files\n const uiFiles = files.filter((f) => f.type === \"registry:ui\");\n if (uiFiles.length < 2) {\n // Single file components don't need subfolders\n return null;\n }\n\n const subfolders = new Set<string>();\n\n for (const file of uiFiles) {\n const parts = file.path.split(\"/\");\n // Look for pattern: .../ui/<subfolder>/<filename>\n const uiIndex = parts.indexOf(\"ui\");\n if (uiIndex !== -1 && parts.length > uiIndex + 2) {\n // There's at least one folder after \"ui\" before the filename\n subfolders.add(parts[uiIndex + 1]);\n }\n }\n\n // If all files share the same subfolder, use it\n if (subfolders.size === 1) {\n return Array.from(subfolders)[0];\n }\n\n // Fallback: use the component name from the first file's parent directory\n if (uiFiles.length > 0) {\n const firstPath = uiFiles[0].path;\n const dirname = path.dirname(firstPath);\n const folderName = path.basename(dirname);\n // Only use if it's not \"ui\" itself\n if (folderName && folderName !== \"ui\") {\n return folderName;\n }\n }\n\n return null;\n}\n\n/**\n * Checks if a path exists.\n */\nasync function pathExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Builds a map of path rewrites for components that will be reorganized.\n * Call this BEFORE shadcn runs to know how to rewrite output paths.\n */\nexport async function buildPathRewriteMap(\n components: string[],\n uiDir: string,\n registryUrl: string,\n): Promise<PathRewriteMap> {\n const rewrites: PathRewriteMap = new Map();\n\n if (!uiDir || components.length === 0) {\n return rewrites;\n }\n\n for (const componentName of components) {\n try {\n const registryItem = await fetchRegistryItem(componentName, registryUrl);\n if (!registryItem) continue;\n\n const subfolder = getSubfolderFromPaths(registryItem.files);\n if (!subfolder) continue;\n\n // Get the UI files that will be reorganized\n const uiFiles = registryItem.files.filter(\n (f) => f.type === \"registry:ui\",\n );\n\n for (const file of uiFiles) {\n const filename = path.basename(file.path);\n // Map: \"Avatar.astro\" → \"avatar/Avatar.astro\"\n rewrites.set(filename, `${subfolder}/${filename}`);\n }\n } catch {\n // Ignore errors, just skip this component\n }\n }\n\n return rewrites;\n}\n\n/**\n * Rewrites file paths in shadcn output to reflect reorganized structure.\n * Replaces flat paths like \"/ui/Avatar.astro\" with \"/ui/avatar/Avatar.astro\"\n */\nexport function rewriteOutputPaths(\n output: string,\n rewrites: PathRewriteMap,\n): string {\n let result = output;\n\n for (const [filename, newPath] of rewrites) {\n // Match paths ending with the filename (handles various path formats)\n // e.g., \"packages/ui/src/components/Avatar.astro\" → \"packages/ui/src/components/avatar/Avatar.astro\"\n const escapedFilename = filename.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const pattern = new RegExp(`(/[^/\\\\s]+)/${escapedFilename}(?=\\\\s|$|\\\\n)`, \"g\");\n result = result.replace(pattern, `$1/${newPath}`);\n }\n\n return result;\n}\n\nexport interface ReorganizeResult {\n totalMoved: number;\n movedFiles: string[]; // e.g., [\"avatar/Avatar.astro\", \"avatar/index.ts\"]\n skippedFiles: string[]; // Files that already existed in subfolder (flat duplicate removed)\n}\n\n/**\n * Reorganizes multi-file components into correct subfolders.\n * Only moves files from FLAT location to subfolder.\n * Does NOT touch files already in subfolders.\n * E.g., moves `uiDir/Avatar.astro` to `uiDir/avatar/Avatar.astro`.\n * Returns info about moved files for display purposes.\n */\nexport async function reorganizeComponents(\n components: string[],\n uiDir: string,\n registryUrl: string,\n verbose: boolean,\n): Promise<ReorganizeResult> {\n const result: ReorganizeResult = { totalMoved: 0, movedFiles: [], skippedFiles: [] };\n\n if (!uiDir || components.length === 0) {\n return result;\n }\n\n for (const componentName of components) {\n try {\n const registryItem = await fetchRegistryItem(componentName, registryUrl);\n if (!registryItem) {\n if (verbose) {\n logger.info(\n `[bejamas-ui] Could not fetch registry for ${componentName}, skipping reorganization`,\n );\n }\n continue;\n }\n\n const subfolder = getSubfolderFromPaths(registryItem.files);\n if (!subfolder) {\n // Single-file component or no subfolder detected, skip\n if (verbose) {\n logger.info(\n `[bejamas-ui] ${componentName} is single-file or has no subfolder, skipping`,\n );\n }\n continue;\n }\n\n // Get the UI files that need to be moved\n const uiFiles = registryItem.files.filter(\n (f) => f.type === \"registry:ui\",\n );\n\n const targetDir = path.join(uiDir, subfolder);\n let movedCount = 0;\n\n for (const file of uiFiles) {\n const filename = path.basename(file.path);\n // Only look for files in FLAT location (directly in uiDir)\n const flatPath = path.join(uiDir, filename);\n const targetPath = path.join(targetDir, filename);\n\n // Check if file exists in flat location\n if (!(await pathExists(flatPath))) {\n // Not in flat location, skip (may already be in subfolder)\n continue;\n }\n\n // Check if target already exists (don't overwrite, but clean up flat duplicate)\n if (await pathExists(targetPath)) {\n // Target exists in subfolder - delete the flat duplicate shadcn just created\n try {\n await fs.unlink(flatPath);\n result.skippedFiles.push(`${subfolder}/${filename}`);\n if (verbose) {\n logger.info(\n `[bejamas-ui] Removed flat duplicate: ${filename} (${subfolder}/${filename} exists)`,\n );\n }\n } catch {\n // Flat file might not exist or already deleted, but still counts as skipped\n result.skippedFiles.push(`${subfolder}/${filename}`);\n }\n continue;\n }\n\n // Create target directory if needed\n await fs.mkdir(targetDir, { recursive: true });\n\n // Move file from flat to subfolder\n await fs.rename(flatPath, targetPath);\n movedCount++;\n result.totalMoved++;\n result.movedFiles.push(`${subfolder}/${filename}`);\n\n if (verbose) {\n logger.info(`[bejamas-ui] Moved ${filename} → ${subfolder}/${filename}`);\n }\n }\n\n if (movedCount > 0 && verbose) {\n logger.info(\n `[bejamas-ui] Reorganized ${componentName} into ${subfolder}/`,\n );\n }\n } catch (err) {\n // Non-fatal: log and continue with other components\n if (verbose) {\n logger.warn(\n `[bejamas-ui] Failed to reorganize ${componentName}: ${err}`,\n );\n }\n }\n }\n\n return result;\n}\n\n","import path from \"node:path\";\nimport { Command } from \"commander\";\nimport { execa } from \"execa\";\nimport { logger } from \"@/src/utils/logger\";\nimport { spinner } from \"@/src/utils/spinner\";\nimport { highlighter } from \"@/src/utils/highlighter\";\nimport { getPackageRunner } from \"@/src/utils/get-package-manager\";\nimport { fixAstroImports } from \"@/src/utils/astro-imports\";\nimport { getConfig, getWorkspaceConfig } from \"@/src/utils/get-config\";\nimport {\n reorganizeComponents,\n fetchRegistryItem,\n getSubfolderFromPaths,\n} from \"@/src/utils/reorganize-components\";\n\ninterface ParsedOutput {\n created: string[];\n updated: string[];\n skipped: string[];\n}\n\n// Default fallback registry endpoint for shadcn (expects /r)\nconst DEFAULT_REGISTRY_URL = \"https://ui.bejamas.com/r\";\n\n// Derive only the user-provided flags for shadcn to avoid losing options\nfunction extractOptionsForShadcn(rawArgv: string[], cmd: Command): string[] {\n // Prefer commander metadata when available so we only forward options that\n // were explicitly set (avoids defaults and keeps aliases consistent).\n if (typeof cmd.getOptionValueSource === \"function\") {\n const opts = cmd.optsWithGlobals() as Record<string, unknown>;\n const forwarded: string[] = [];\n const getSource = (key: string) => cmd.getOptionValueSource(key);\n\n const addBoolean = (key: string, flag: string, negateFlag?: string) => {\n if (getSource(key) !== \"cli\") return;\n const value = opts[key];\n if (typeof value !== \"boolean\") return;\n if (value) {\n forwarded.push(flag);\n } else if (negateFlag) {\n forwarded.push(negateFlag);\n }\n };\n\n const addString = (key: string, flag: string) => {\n if (getSource(key) !== \"cli\") return;\n const value = opts[key];\n if (typeof value === \"string\") {\n forwarded.push(flag, value);\n }\n };\n\n addBoolean(\"yes\", \"--yes\");\n addBoolean(\"overwrite\", \"--overwrite\");\n addString(\"cwd\", \"--cwd\");\n addBoolean(\"all\", \"--all\");\n addString(\"path\", \"--path\");\n addBoolean(\"silent\", \"--silent\");\n addBoolean(\"srcDir\", \"--src-dir\", \"--no-src-dir\");\n\n // Preserve any explicit passthrough after \"--\" for shadcn.\n const addIndex = rawArgv.findIndex((arg) => arg === \"add\");\n if (addIndex !== -1) {\n const rest = rawArgv.slice(addIndex + 1);\n const doubleDashIndex = rest.indexOf(\"--\");\n if (doubleDashIndex !== -1) {\n forwarded.push(...rest.slice(doubleDashIndex));\n }\n }\n\n return forwarded;\n }\n\n // Fallback: lightweight parser that only forwards known options.\n const addIndex = rawArgv.findIndex((arg) => arg === \"add\");\n if (addIndex === -1) return [];\n const rest = rawArgv.slice(addIndex + 1);\n const forwarded: string[] = [];\n const optionsWithValues = new Set([\"-c\", \"--cwd\", \"-p\", \"--path\"]);\n const filteredFlags = new Set([\"-v\", \"--verbose\"]);\n\n for (let i = 0; i < rest.length; i += 1) {\n const token = rest[i];\n if (token === \"--\") {\n forwarded.push(\"--\", ...rest.slice(i + 1));\n break;\n }\n if (!token.startsWith(\"-\")) continue;\n if (filteredFlags.has(token)) continue;\n\n forwarded.push(token);\n if (token.includes(\"=\")) continue;\n\n if (optionsWithValues.has(token)) {\n const next = rest[i + 1];\n if (next) {\n forwarded.push(next);\n i += 1;\n }\n }\n }\n return forwarded;\n}\n\ninterface ComponentFileInfo {\n subfolder: string;\n files: string[]; // All filenames for this component\n}\n\ninterface SubfolderMapResult {\n // Maps unique filename -> subfolder/filename\n uniqueMap: Map<string, string>;\n // Maps component subfolder -> all its files (for grouping)\n componentInfo: Map<string, ComponentFileInfo>;\n // Set of shared filenames (like index.ts) that appear in multiple components\n sharedFilenames: Set<string>;\n}\n\n/** Build maps for path rewriting, handling filename collisions */\nasync function buildSubfolderMap(\n components: string[],\n registryUrl: string,\n): Promise<SubfolderMapResult> {\n const filenameToSubfolders = new Map<string, string[]>();\n const componentInfo = new Map<string, ComponentFileInfo>();\n\n // First pass: collect all filename -> subfolder mappings\n for (const componentName of components) {\n const registryItem = await fetchRegistryItem(componentName, registryUrl);\n if (!registryItem) continue;\n\n const subfolder = getSubfolderFromPaths(registryItem.files);\n if (!subfolder) continue;\n\n const files: string[] = [];\n for (const file of registryItem.files) {\n if (file.type === \"registry:ui\") {\n const filename = path.basename(file.path);\n files.push(filename);\n\n // Track which subfolders each filename appears in\n const subfolders = filenameToSubfolders.get(filename) || [];\n subfolders.push(subfolder);\n filenameToSubfolders.set(filename, subfolders);\n }\n }\n\n componentInfo.set(subfolder, { subfolder, files });\n }\n\n // Build the unique map (only filenames that appear once)\n const uniqueMap = new Map<string, string>();\n const sharedFilenames = new Set<string>();\n\n filenameToSubfolders.forEach((subfolders, filename) => {\n if (subfolders.length === 1) {\n // Unique filename - safe to map directly\n uniqueMap.set(filename, `${subfolders[0]}/${filename}`);\n } else {\n // Shared filename (like index.ts) - track for context-based rewriting\n sharedFilenames.add(filename);\n }\n });\n\n return { uniqueMap, componentInfo, sharedFilenames };\n}\n\n/**\n * Rewrite file paths to include correct subfolders.\n * Handles shared filenames (like index.ts) by tracking current component context.\n */\nfunction rewritePaths(\n paths: string[],\n mapResult: SubfolderMapResult,\n): string[] {\n const { uniqueMap, componentInfo, sharedFilenames } = mapResult;\n let currentSubfolder: string | null = null;\n\n return paths.map((filePath) => {\n const filename = path.basename(filePath);\n const parentDir = path.basename(path.dirname(filePath));\n\n // Check if this is a unique filename (can map directly)\n const uniqueMapping = uniqueMap.get(filename);\n if (uniqueMapping) {\n const expectedSubfolder = path.dirname(uniqueMapping);\n\n // Update current context for subsequent shared files\n currentSubfolder = expectedSubfolder;\n\n // Only rewrite if not already in the correct subfolder\n if (parentDir !== expectedSubfolder) {\n const dir = path.dirname(filePath);\n return `${dir}/${uniqueMapping}`;\n }\n return filePath;\n }\n\n // Check if this is a shared filename (like index.ts)\n if (sharedFilenames.has(filename) && currentSubfolder) {\n // Use the current component context\n const expectedSubfolder = currentSubfolder;\n\n // Only rewrite if not already in the correct subfolder\n if (parentDir !== expectedSubfolder) {\n const dir = path.dirname(filePath);\n return `${dir}/${expectedSubfolder}/${filename}`;\n }\n }\n\n return filePath;\n });\n}\n\n/** Parse shadcn output to extract file lists (stdout has paths, stderr has headers) */\nfunction parseShadcnOutput(stdout: string, stderr: string): ParsedOutput {\n const result: ParsedOutput = { created: [], updated: [], skipped: [] };\n\n // Remove ANSI escape codes for parsing\n const cleanStderr = stderr.replace(/\\x1b\\[[0-9;]*m/g, \"\");\n const cleanStdout = stdout.replace(/\\x1b\\[[0-9;]*m/g, \"\");\n\n // Extract counts from stderr headers\n // Matches patterns like \"✔ Created 4 files:\" or \"ℹ Skipped 2 files:\"\n const createdMatch = cleanStderr.match(/Created\\s+(\\d+)\\s+file/i);\n const updatedMatch = cleanStderr.match(/Updated\\s+(\\d+)\\s+file/i);\n const skippedMatch = cleanStderr.match(/Skipped\\s+(\\d+)\\s+file/i);\n\n const createdCount = createdMatch ? parseInt(createdMatch[1], 10) : 0;\n const updatedCount = updatedMatch ? parseInt(updatedMatch[1], 10) : 0;\n const skippedCount = skippedMatch ? parseInt(skippedMatch[1], 10) : 0;\n\n // Extract file paths from stdout (lines starting with \" - \")\n const allPaths: string[] = [];\n for (const line of cleanStdout.split(\"\\n\")) {\n const match = line.match(/^\\s+-\\s+(.+)$/);\n if (match) {\n allPaths.push(match[1].trim());\n }\n }\n\n // Also check stderr for file paths (some shadcn versions output there)\n for (const line of cleanStderr.split(\"\\n\")) {\n const match = line.match(/^\\s+-\\s+(.+)$/);\n if (match) {\n const filePath = match[1].trim();\n // Avoid duplicates\n if (!allPaths.includes(filePath)) {\n allPaths.push(filePath);\n }\n }\n }\n\n // Assign paths to sections based on counts (order: created, updated, skipped)\n let idx = 0;\n for (let i = 0; i < createdCount && idx < allPaths.length; i++) {\n result.created.push(allPaths[idx++]);\n }\n for (let i = 0; i < updatedCount && idx < allPaths.length; i++) {\n result.updated.push(allPaths[idx++]);\n }\n for (let i = 0; i < skippedCount && idx < allPaths.length; i++) {\n result.skipped.push(allPaths[idx++]);\n }\n\n return result;\n}\n\nasync function addComponents(\n packages: string[],\n forwardedOptions: string[],\n isVerbose: boolean,\n isSilent: boolean,\n subfolderMapResult: SubfolderMapResult,\n): Promise<ParsedOutput> {\n const runner = await getPackageRunner(process.cwd());\n const env = {\n ...process.env,\n REGISTRY_URL: process.env.REGISTRY_URL || DEFAULT_REGISTRY_URL,\n };\n // Always pass --yes for non-interactive mode (skips \"Add components?\" confirmation)\n // Note: we don't pass --overwrite by default to respect user customizations\n const autoFlags: string[] = [];\n if (!forwardedOptions.includes(\"--yes\")) {\n autoFlags.push(\"--yes\");\n }\n const baseArgs = [\n \"shadcn@latest\",\n \"add\",\n ...packages,\n ...autoFlags,\n ...forwardedOptions,\n ];\n\n let cmd = \"npx\";\n let args: string[] = [\"-y\", ...baseArgs];\n if (runner === \"bunx\") {\n cmd = \"bunx\";\n args = baseArgs;\n } else if (runner === \"pnpm dlx\") {\n cmd = \"pnpm\";\n args = [\"dlx\", ...baseArgs];\n } else if (runner === \"npx\") {\n cmd = \"npx\";\n args = [\"-y\", ...baseArgs];\n }\n\n if (isVerbose) {\n logger.info(`[bejamas-ui] ${cmd} ${args.join(\" \")}`);\n }\n\n // Show our own spinner for checking registry\n const registrySpinner = spinner(\"Checking registry.\", { silent: isSilent });\n registrySpinner.start();\n\n try {\n // Run shadcn and capture output\n // Pipe \"n\" to stdin to answer \"no\" to any overwrite prompts (respects user customizations)\n const result = await execa(cmd, args, {\n env,\n input: \"n\\nn\\nn\\nn\\nn\\nn\\nn\\nn\\nn\\nn\\n\", // Answer \"no\" to up to 10 overwrite prompts\n stdout: \"pipe\",\n stderr: \"pipe\",\n reject: false,\n });\n\n registrySpinner.succeed();\n\n // Show installing spinner (already done at this point)\n const installSpinner = spinner(\"Installing components.\", {\n silent: isSilent,\n });\n installSpinner.succeed();\n\n // Parse the output to get file lists (stdout has paths, stderr has headers)\n const stdout = result.stdout || \"\";\n const stderr = result.stderr || \"\";\n\n if (isVerbose) {\n logger.info(`[bejamas-ui] Raw stdout: ${stdout}`);\n logger.info(`[bejamas-ui] Raw stderr: ${stderr}`);\n }\n\n const parsed = parseShadcnOutput(stdout, stderr);\n\n // Return parsed data - display is handled by caller after reorganization\n // This allows accurate reporting (shadcn says \"created\" but we may skip)\n\n if (result.exitCode !== 0) {\n // Show any error output\n if (result.stderr) {\n logger.error(result.stderr);\n }\n process.exit(result.exitCode);\n }\n\n return parsed;\n } catch (err) {\n registrySpinner.fail();\n logger.error(\"Failed to add components\");\n process.exit(1);\n }\n}\n\nexport const add = new Command()\n .name(\"add\")\n .description(\"Add components via shadcn@latest using registry URLs\")\n .argument(\"[components...]\", \"Component package names to add\")\n .option(\"-y, --yes\", \"skip confirmation prompt.\", false)\n .option(\"-o, --overwrite\", \"overwrite existing files.\", false)\n .option(\n \"-c, --cwd <cwd>\",\n \"the working directory. defaults to the current directory.\",\n process.cwd(),\n )\n .option(\"-a, --all\", \"add all available components\", false)\n .option(\"-p, --path <path>\", \"the path to add the component to.\")\n .option(\"-s, --silent\", \"mute output.\", false)\n .option(\n \"--src-dir\",\n \"use the src directory when creating a new project.\",\n false,\n )\n .option(\n \"--no-src-dir\",\n \"do not use the src directory when creating a new project.\",\n )\n // .option(\"--css-variables\", \"use css variables for theming.\", true)\n // .option(\"--no-css-variables\", \"do not use css variables for theming.\")\n .action(async function action(packages: string[], _opts, cmd) {\n const root = cmd?.parent;\n const verbose = Boolean(root?.opts?.().verbose);\n const rawArgv = process.argv.slice(2);\n const forwardedOptions = extractOptionsForShadcn(rawArgv, cmd);\n const opts =\n typeof cmd.optsWithGlobals === \"function\"\n ? cmd.optsWithGlobals()\n : (cmd.opts?.() ?? {});\n const cwd = opts.cwd || process.cwd();\n\n // Get config for resolved paths (needed for reorganization)\n // In monorepos, we need to follow the alias chain to find the actual UI package config\n const config = await getConfig(cwd);\n const registryUrl = process.env.REGISTRY_URL || DEFAULT_REGISTRY_URL;\n\n // Try to get workspace config (follows aliases to find package-specific configs)\n let uiDir = config?.resolvedPaths?.ui || \"\";\n let uiConfig = config;\n\n if (config) {\n const workspaceConfig = await getWorkspaceConfig(config);\n if (workspaceConfig?.ui) {\n // Use the UI package's own config (e.g., packages/ui/components.json)\n uiConfig = workspaceConfig.ui;\n uiDir = uiConfig.resolvedPaths?.ui || uiDir;\n }\n }\n\n if (verbose) {\n logger.info(`[bejamas-ui] cwd: ${cwd}`);\n logger.info(`[bejamas-ui] uiDir: ${uiDir}`);\n logger.info(\n `[bejamas-ui] aliases.ui: ${uiConfig?.aliases?.ui || \"not set\"}`,\n );\n }\n\n // Process components ONE AT A TIME to avoid index.ts conflicts\n // When shadcn runs with multiple components, files with same name overwrite each other\n const isSilent = opts.silent || false;\n const componentsToAdd = packages || [];\n const totalComponents = componentsToAdd.length;\n\n for (let i = 0; i < componentsToAdd.length; i++) {\n const component = componentsToAdd[i];\n\n // Show component header when adding multiple\n if (totalComponents > 1 && !isSilent) {\n logger.break();\n logger.info(\n highlighter.info(`[${i + 1}/${totalComponents}]`) +\n ` Adding ${highlighter.success(component)}...`,\n );\n }\n\n // Build subfolder map for this single component\n const subfolderMapResult = await buildSubfolderMap(\n [component],\n registryUrl,\n );\n\n // Run shadcn for just this component\n const parsed = await addComponents(\n [component],\n forwardedOptions,\n verbose,\n isSilent,\n subfolderMapResult,\n );\n\n // Immediately reorganize this component's files before the next one\n let skippedCount = 0;\n if (uiDir) {\n const reorgResult = await reorganizeComponents(\n [component],\n uiDir,\n registryUrl,\n verbose,\n );\n skippedCount = reorgResult.skippedFiles.length;\n }\n\n // Display accurate results (accounting for files we skipped after shadcn \"created\" them)\n if (!isSilent) {\n const relativeUiDir = uiDir ? path.relative(cwd, uiDir) : \"\";\n\n // Files that were actually created (shadcn created minus our skipped)\n const actuallyCreated = Math.max(\n 0,\n parsed.created.length - skippedCount,\n );\n\n if (actuallyCreated > 0) {\n const createdPaths = rewritePaths(\n parsed.created.slice(0, actuallyCreated),\n subfolderMapResult,\n );\n logger.success(\n `Created ${createdPaths.length} file${createdPaths.length > 1 ? \"s\" : \"\"}:`,\n );\n for (const file of createdPaths) {\n logger.log(` ${highlighter.info(\"-\")} ${file}`);\n }\n }\n\n // Updated files (globals.css etc)\n if (parsed.updated.length > 0) {\n const uniqueUpdated = Array.from(new Set(parsed.updated));\n const updatedPaths = rewritePaths(uniqueUpdated, subfolderMapResult);\n logger.info(\n `Updated ${updatedPaths.length} file${updatedPaths.length > 1 ? \"s\" : \"\"}:`,\n );\n for (const file of updatedPaths) {\n logger.log(` ${highlighter.info(\"-\")} ${file}`);\n }\n }\n\n // Files skipped because they already exist in subfolder\n if (skippedCount > 0) {\n logger.info(\n `Skipped ${skippedCount} file${skippedCount > 1 ? \"s\" : \"\"}: (already exists)`,\n );\n }\n\n // Files shadcn skipped (different from our reorganization skip)\n if (parsed.skipped.length > 0) {\n const skippedPaths = rewritePaths(parsed.skipped, subfolderMapResult);\n logger.info(\n `Skipped ${skippedPaths.length} file${skippedPaths.length > 1 ? \"s\" : \"\"}: (use --overwrite)`,\n );\n for (const file of skippedPaths) {\n logger.log(` ${highlighter.info(\"-\")} ${file}`);\n }\n }\n\n // Nothing happened\n if (\n actuallyCreated === 0 &&\n parsed.updated.length === 0 &&\n skippedCount === 0 &&\n parsed.skipped.length === 0\n ) {\n logger.info(\"Already up to date.\");\n }\n }\n }\n\n // Fix aliases inside Astro files until upstream adds .astro support.\n await fixAstroImports(cwd, verbose);\n });\n","#!/usr/bin/env node\n\nimport { Command } from \"commander\";\nimport { createRequire } from \"module\";\nimport { init } from \"@/src/commands/init\";\nimport { docs } from \"@/src/commands/docs\";\nimport { docsCheck } from \"@/src/commands/docs-check\";\nimport { add } from \"@/src/commands/add\";\n\nconst require = createRequire(import.meta.url);\nconst pkg = require(\"../package.json\");\n\nconst program = new Command()\n .name(\"bejamas\")\n .description(\"bejamas/ui cli\")\n .configureHelp({\n helpWidth: Math.min(100, process.stdout.columns || 100),\n })\n .version(pkg.version, \"-v, --version\", \"output the version number\");\n\nprogram.addCommand(init);\nprogram.addCommand(add);\nprogram.addCommand(docs);\nprogram.addCommand(docsCheck);\n\nprogram.parse(process.argv);\n\nexport default program;\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["errors: Record<string, boolean>","fs","ERRORS.MISSING_DIR_OR_EMPTY_PROJECT","context: RegistryContext","template: keyof typeof TEMPLATES","projectName: string","fs","TEMPLATE_TAR_SUBPATH: Record<keyof typeof TEMPLATES, string>","headers: Record<string, string>","DEFAULT_REGISTRY_URL","ERRORS.MISSING_DIR_OR_EMPTY_PROJECT","baseUrl: string","paths: Record<string, string[] | string>","probe: string | null","mapped: string","uiAbs: string | null","cssAbs: string | null","outResolved: string | null","relative","err: any","FIELD_LABELS: Record<string, string>","missingRequired: string[]","missingRecommended: string[]","status: \"complete\" | \"incomplete\" | \"missing\"","probe: string | null","mapped: string","uiAbs: string | null","cssAbs: string | null","uiRoot: string","join","extname","results: ComponentDocStatus[]","checkResult: CheckResult","err: any","path","dirname","path","result: ReorganizeResult","forwarded: string[]","addIndex","rest","forwarded","files: string[]","path","currentSubfolder: string | null","components: { name: string; type?: string }[]","result: ParsedOutput","allPaths: string[]","autoFlags: string[]","args: string[]"],"sources":["../src/utils/errors.ts","../src/preflights/preflight-init.ts","../src/registry/context.ts","../src/utils/get-package-manager.ts","../src/registry/errors.ts","../src/utils/handle-error.ts","../src/utils/create-project.ts","../src/commands/init.ts","../src/utils/tsconfig-utils.ts","../src/commands/docs.ts","../src/commands/docs-check.ts","../src/utils/astro-imports.ts","../src/utils/reorganize-components.ts","../src/commands/add.ts","../src/index.ts"],"sourcesContent":["export const MISSING_DIR_OR_EMPTY_PROJECT = \"1\";\nexport const EXISTING_CONFIG = \"2\";\nexport const MISSING_CONFIG = \"3\";\nexport const FAILED_CONFIG_READ = \"4\";\nexport const TAILWIND_NOT_CONFIGURED = \"5\";\nexport const IMPORT_ALIAS_MISSING = \"6\";\nexport const UNSUPPORTED_FRAMEWORK = \"7\";\nexport const COMPONENT_URL_NOT_FOUND = \"8\";\nexport const COMPONENT_URL_UNAUTHORIZED = \"9\";\nexport const COMPONENT_URL_FORBIDDEN = \"10\";\nexport const COMPONENT_URL_BAD_REQUEST = \"11\";\nexport const COMPONENT_URL_INTERNAL_SERVER_ERROR = \"12\";\nexport const BUILD_MISSING_REGISTRY_FILE = \"13\";\n","import path from \"path\";\nimport { initOptionsSchema } from \"@/src/commands/init\";\nimport * as ERRORS from \"@/src/utils/errors\";\nimport fs from \"fs-extra\";\nimport { z } from \"zod\";\n\nexport async function preFlightInit(\n options: z.infer<typeof initOptionsSchema>,\n) {\n const errors: Record<string, boolean> = {};\n\n // Ensure target directory exists.\n // Check for empty project. We assume if no package.json exists, the project is empty.\n if (\n !fs.existsSync(options.cwd) ||\n !fs.existsSync(path.resolve(options.cwd, \"package.json\"))\n ) {\n errors[ERRORS.MISSING_DIR_OR_EMPTY_PROJECT] = true;\n return {\n errors,\n projectInfo: null,\n };\n }\n\n return {\n errors,\n projectInfo: null,\n };\n}\n","interface RegistryContext {\n headers: Record<string, Record<string, string>>;\n}\n\nlet context: RegistryContext = {\n headers: {},\n};\n\nexport function setRegistryHeaders(\n headers: Record<string, Record<string, string>>,\n) {\n // Merge new headers with existing ones to preserve headers for nested dependencies\n context.headers = { ...context.headers, ...headers };\n}\n\nexport function getRegistryHeadersFromContext(\n url: string,\n): Record<string, string> {\n return context.headers[url] || {};\n}\n\nexport function clearRegistryContext() {\n context.headers = {};\n}\n","import { detect } from \"@antfu/ni\";\n\nexport async function getPackageManager(\n targetDir: string,\n { withFallback }: { withFallback?: boolean } = {\n withFallback: false,\n },\n): Promise<\"yarn\" | \"pnpm\" | \"bun\" | \"npm\" | \"deno\"> {\n const packageManager = await detect({ programmatic: true, cwd: targetDir });\n\n if (packageManager === \"yarn@berry\") return \"yarn\";\n if (packageManager === \"pnpm@6\") return \"pnpm\";\n if (packageManager === \"bun\") return \"bun\";\n if (packageManager === \"deno\") return \"deno\";\n if (!withFallback) {\n return packageManager ?? \"npm\";\n }\n\n // Fallback to user agent if not detected.\n const userAgent = process.env.npm_config_user_agent || \"\";\n\n if (userAgent.startsWith(\"yarn\")) {\n return \"yarn\";\n }\n\n if (userAgent.startsWith(\"pnpm\")) {\n return \"pnpm\";\n }\n\n if (userAgent.startsWith(\"bun\")) {\n return \"bun\";\n }\n\n return \"npm\";\n}\n\nexport async function getPackageRunner(cwd: string) {\n const packageManager = await getPackageManager(cwd);\n\n if (packageManager === \"pnpm\") return \"pnpm dlx\";\n\n if (packageManager === \"bun\") return \"bunx\";\n\n return \"npx\";\n}\n","import { z } from \"zod\";\n\n// Error codes for programmatic error handling\nexport const RegistryErrorCode = {\n // Network errors\n NETWORK_ERROR: \"NETWORK_ERROR\",\n NOT_FOUND: \"NOT_FOUND\",\n UNAUTHORIZED: \"UNAUTHORIZED\",\n FORBIDDEN: \"FORBIDDEN\",\n FETCH_ERROR: \"FETCH_ERROR\",\n\n // Configuration errors\n NOT_CONFIGURED: \"NOT_CONFIGURED\",\n INVALID_CONFIG: \"INVALID_CONFIG\",\n MISSING_ENV_VARS: \"MISSING_ENV_VARS\",\n\n // File system errors\n LOCAL_FILE_ERROR: \"LOCAL_FILE_ERROR\",\n\n // Parsing errors\n PARSE_ERROR: \"PARSE_ERROR\",\n VALIDATION_ERROR: \"VALIDATION_ERROR\",\n\n // Generic errors\n UNKNOWN_ERROR: \"UNKNOWN_ERROR\",\n} as const;\n\nexport type RegistryErrorCode =\n (typeof RegistryErrorCode)[keyof typeof RegistryErrorCode];\n\nexport class RegistryError extends Error {\n public readonly code: RegistryErrorCode;\n public readonly statusCode?: number;\n public readonly context?: Record<string, unknown>;\n public readonly suggestion?: string;\n public readonly timestamp: Date;\n public readonly cause?: unknown;\n\n constructor(\n message: string,\n options: {\n code?: RegistryErrorCode;\n statusCode?: number;\n cause?: unknown;\n context?: Record<string, unknown>;\n suggestion?: string;\n } = {},\n ) {\n super(message);\n this.name = \"RegistryError\";\n this.code = options.code || RegistryErrorCode.UNKNOWN_ERROR;\n this.statusCode = options.statusCode;\n this.cause = options.cause;\n this.context = options.context;\n this.suggestion = options.suggestion;\n this.timestamp = new Date();\n\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n\n toJSON() {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n statusCode: this.statusCode,\n context: this.context,\n suggestion: this.suggestion,\n timestamp: this.timestamp,\n stack: this.stack,\n };\n }\n}\n\nexport class RegistryNotFoundError extends RegistryError {\n constructor(\n public readonly url: string,\n cause?: unknown,\n ) {\n const message = `The item at ${url} was not found. It may not exist at the registry.`;\n\n super(message, {\n code: RegistryErrorCode.NOT_FOUND,\n statusCode: 404,\n cause,\n context: { url },\n suggestion:\n \"Check if the item name is correct and the registry URL is accessible.\",\n });\n this.name = \"RegistryNotFoundError\";\n }\n}\n\nexport class RegistryUnauthorizedError extends RegistryError {\n constructor(\n public readonly url: string,\n cause?: unknown,\n ) {\n const message = `You are not authorized to access the item at ${url}. If this is a remote registry, you may need to authenticate.`;\n\n super(message, {\n code: RegistryErrorCode.UNAUTHORIZED,\n statusCode: 401,\n cause,\n context: { url },\n suggestion:\n \"Check your authentication credentials and environment variables.\",\n });\n this.name = \"RegistryUnauthorizedError\";\n }\n}\n\nexport class RegistryForbiddenError extends RegistryError {\n constructor(\n public readonly url: string,\n cause?: unknown,\n ) {\n const message = `You are not authorized to access the item at ${url}. If this is a remote registry, you may need to authenticate.`;\n\n super(message, {\n code: RegistryErrorCode.FORBIDDEN,\n statusCode: 403,\n cause,\n context: { url },\n suggestion:\n \"Check your authentication credentials and environment variables.\",\n });\n this.name = \"RegistryForbiddenError\";\n }\n}\n\nexport class RegistryFetchError extends RegistryError {\n constructor(\n public readonly url: string,\n statusCode?: number,\n public readonly responseBody?: string,\n cause?: unknown,\n ) {\n // Use the error detail from the server if available\n const baseMessage = statusCode\n ? `Failed to fetch from registry (${statusCode}): ${url}`\n : `Failed to fetch from registry: ${url}`;\n\n const message =\n typeof cause === \"string\" && cause\n ? `${baseMessage} - ${cause}`\n : baseMessage;\n\n let suggestion = \"Check your network connection and try again.\";\n if (statusCode === 404) {\n suggestion =\n \"The requested resource was not found. Check the URL or item name.\";\n } else if (statusCode === 500) {\n suggestion = \"The registry server encountered an error. Try again later.\";\n } else if (statusCode && statusCode >= 400 && statusCode < 500) {\n suggestion = \"There was a client error. Check your request parameters.\";\n }\n\n super(message, {\n code: RegistryErrorCode.FETCH_ERROR,\n statusCode,\n cause,\n context: { url, responseBody },\n suggestion,\n });\n this.name = \"RegistryFetchError\";\n }\n}\n\nexport class RegistryNotConfiguredError extends RegistryError {\n constructor(public readonly registryName: string | null) {\n const message = registryName\n ? `Unknown registry \"${registryName}\". Make sure it is defined in components.json as follows:\n{\n \"registries\": {\n \"${registryName}\": \"[URL_TO_REGISTRY]\"\n }\n}`\n : `Unknown registry. Make sure it is defined in components.json under \"registries\".`;\n\n super(message, {\n code: RegistryErrorCode.NOT_CONFIGURED,\n context: { registryName },\n suggestion:\n \"Add the registry configuration to your components.json file. Consult the registry documentation for the correct format.\",\n });\n this.name = \"RegistryNotConfiguredError\";\n }\n}\n\nexport class RegistryLocalFileError extends RegistryError {\n constructor(\n public readonly filePath: string,\n cause?: unknown,\n ) {\n super(`Failed to read local registry file: ${filePath}`, {\n code: RegistryErrorCode.LOCAL_FILE_ERROR,\n cause,\n context: { filePath },\n suggestion: \"Check if the file exists and you have read permissions.\",\n });\n this.name = \"RegistryLocalFileError\";\n }\n}\n\nexport class RegistryParseError extends RegistryError {\n public readonly parseError: unknown;\n\n constructor(\n public readonly item: string,\n parseError: unknown,\n ) {\n let message = `Failed to parse registry item: ${item}`;\n\n if (parseError instanceof z.ZodError) {\n message = `Failed to parse registry item: ${item}\\n${parseError.errors\n .map((e) => ` - ${e.path.join(\".\")}: ${e.message}`)\n .join(\"\\n\")}`;\n }\n\n super(message, {\n code: RegistryErrorCode.PARSE_ERROR,\n cause: parseError,\n context: { item },\n suggestion:\n \"The registry item may be corrupted or have an invalid format. Please make sure it returns a valid JSON object. See https://ui.shadcn.com/schema/registry-item.json.\",\n });\n\n this.parseError = parseError;\n this.name = \"RegistryParseError\";\n }\n}\n\nexport class RegistryMissingEnvironmentVariablesError extends RegistryError {\n constructor(\n public readonly registryName: string,\n public readonly missingVars: string[],\n ) {\n const message =\n `Registry \"${registryName}\" requires the following environment variables:\\n\\n` +\n missingVars.map((v) => ` • ${v}`).join(\"\\n\");\n\n super(message, {\n code: RegistryErrorCode.MISSING_ENV_VARS,\n context: { registryName, missingVars },\n suggestion:\n \"Set the required environment variables to your .env or .env.local file.\",\n });\n this.name = \"RegistryMissingEnvironmentVariablesError\";\n }\n}\n\nexport class RegistryInvalidNamespaceError extends RegistryError {\n constructor(public readonly name: string) {\n const message = `Invalid registry namespace: \"${name}\". Registry names must start with @ (e.g., @shadcn, @v0).`;\n\n super(message, {\n code: RegistryErrorCode.VALIDATION_ERROR,\n context: { name },\n suggestion:\n \"Use a valid registry name starting with @ or provide a direct URL to the registry.\",\n });\n this.name = \"RegistryInvalidNamespaceError\";\n }\n}\n\nexport class ConfigMissingError extends RegistryError {\n constructor(public readonly cwd: string) {\n const message = `No components.json found in ${cwd} or parent directories.`;\n\n super(message, {\n code: RegistryErrorCode.NOT_CONFIGURED,\n context: { cwd },\n suggestion:\n \"Run 'npx shadcn@latest init' to create a components.json file, or check that you're in the correct directory.\",\n });\n this.name = \"ConfigMissingError\";\n }\n}\n\nexport class ConfigParseError extends RegistryError {\n constructor(\n public readonly cwd: string,\n parseError: unknown,\n ) {\n let message = `Invalid components.json configuration in ${cwd}.`;\n\n if (parseError instanceof z.ZodError) {\n message = `Invalid components.json configuration in ${cwd}:\\n${parseError.errors\n .map((e) => ` - ${e.path.join(\".\")}: ${e.message}`)\n .join(\"\\n\")}`;\n }\n\n super(message, {\n code: RegistryErrorCode.INVALID_CONFIG,\n cause: parseError,\n context: { cwd },\n suggestion:\n \"Check your components.json file for syntax errors or invalid configuration. Run 'npx shadcn@latest init' to regenerate a valid configuration.\",\n });\n this.name = \"ConfigParseError\";\n }\n}\n","import { RegistryError } from \"@/src/registry/errors\";\nimport { highlighter } from \"@/src/utils/highlighter\";\nimport { logger } from \"@/src/utils/logger\";\nimport { z } from \"zod\";\n\nexport function handleError(error: unknown) {\n logger.break();\n logger.error(\n `Something went wrong. Please check the error below for more details.`,\n );\n logger.error(\n `If the problem persists, please open an issue on GitHub: https://github.com/bejamas/ui/issues`,\n );\n logger.error(\"\");\n if (typeof error === \"string\") {\n logger.error(error);\n logger.break();\n process.exit(1);\n }\n\n if (error instanceof RegistryError) {\n if (error.message) {\n logger.error(error.cause ? \"Error:\" : \"Message:\");\n logger.error(error.message);\n }\n\n if (error.cause) {\n logger.error(\"\\nMessage:\");\n logger.error(error.cause);\n }\n\n if (error.suggestion) {\n logger.error(\"\\nSuggestion:\");\n logger.error(error.suggestion);\n }\n logger.break();\n process.exit(1);\n }\n\n if (error instanceof z.ZodError) {\n logger.error(\"Validation failed:\");\n for (const [key, value] of Object.entries(error.flatten().fieldErrors)) {\n logger.error(`- ${highlighter.info(key)}: ${value}`);\n }\n logger.break();\n process.exit(1);\n }\n\n if (error instanceof Error) {\n logger.error(error.message);\n logger.break();\n process.exit(1);\n }\n\n logger.break();\n process.exit(1);\n}\n","import os from \"os\";\nimport path from \"path\";\nimport dotenv from \"dotenv\";\nimport { initOptionsSchema } from \"@/src/commands/init\";\nimport { getPackageManager } from \"@/src/utils/get-package-manager\";\nimport { handleError } from \"@/src/utils/handle-error\";\nimport { highlighter } from \"@/src/utils/highlighter\";\nimport { logger } from \"@/src/utils/logger\";\nimport { spinner } from \"@/src/utils/spinner\";\nimport { execa } from \"execa\";\nimport fs from \"fs-extra\";\nimport prompts from \"prompts\";\nimport { z } from \"zod\";\n\nexport const TEMPLATES = {\n astro: \"astro\",\n \"astro-monorepo\": \"astro-monorepo\",\n \"astro-with-component-docs-monorepo\": \"astro-with-component-docs-monorepo\",\n} as const;\n\nconst MONOREPO_TEMPLATE_URL =\n \"https://codeload.github.com/bejamas/ui/tar.gz/main\";\n\nexport async function createProject(\n options: Pick<\n z.infer<typeof initOptionsSchema>,\n \"cwd\" | \"force\" | \"srcDir\" | \"components\" | \"template\"\n >,\n) {\n options = {\n srcDir: false,\n ...options,\n };\n\n let template: keyof typeof TEMPLATES =\n options.template && TEMPLATES[options.template as keyof typeof TEMPLATES]\n ? (options.template as keyof typeof TEMPLATES)\n : \"astro\";\n\n let projectName: string = \"my-app\";\n\n const isRemoteComponent =\n options.components?.length === 1 &&\n !!options.components[0].match(/\\/chat\\/b\\//);\n\n if (!options.force) {\n const { type, name } = await prompts([\n {\n type: options.template || isRemoteComponent ? null : \"select\",\n name: \"type\",\n message: `The path ${highlighter.info(\n options.cwd,\n )} does not contain a package.json file.\\n Would you like to start a new project?`,\n choices: [\n { title: \"Astro\", value: \"astro\" },\n { title: \"Astro (Monorepo)\", value: \"astro-monorepo\" },\n {\n title: \"Astro with Component Docs (Monorepo)\",\n value: \"astro-with-component-docs-monorepo\",\n },\n ],\n initial: 0,\n },\n {\n type: \"text\",\n name: \"name\",\n message: \"What is your project named?\",\n initial: (_prev: any, values: any) => {\n const selectedTemplate: string =\n (options.template &&\n TEMPLATES[options.template as keyof typeof TEMPLATES] &&\n options.template) ||\n values.type ||\n template;\n return selectedTemplate?.endsWith(\"monorepo\")\n ? \"my-monorepo\"\n : \"my-app\";\n },\n format: (value: string) => value.trim(),\n validate: (value: string) =>\n value.length > 128\n ? `Name should be less than 128 characters.`\n : true,\n },\n ]);\n\n template = type ?? template;\n projectName = name;\n }\n\n const packageManager = await getPackageManager(options.cwd, {\n withFallback: true,\n });\n\n const projectPath = `${options.cwd}/${projectName}`;\n\n // Check if path is writable.\n try {\n await fs.access(options.cwd, fs.constants.W_OK);\n } catch (error) {\n logger.break();\n logger.error(`The path ${highlighter.info(options.cwd)} is not writable.`);\n logger.error(\n `It is likely you do not have write permissions for this folder or the path ${highlighter.info(\n options.cwd,\n )} does not exist.`,\n );\n logger.break();\n process.exit(1);\n }\n\n if (fs.existsSync(path.resolve(options.cwd, projectName, \"package.json\"))) {\n logger.break();\n logger.error(\n `A project with the name ${highlighter.info(projectName)} already exists.`,\n );\n logger.error(`Please choose a different name and try again.`);\n logger.break();\n process.exit(1);\n }\n\n await createProjectFromTemplate(projectPath, {\n templateKey: template,\n packageManager,\n cwd: options.cwd,\n });\n\n return {\n projectPath,\n projectName,\n template,\n };\n}\n\nasync function createProjectFromTemplate(\n projectPath: string,\n options: {\n templateKey: keyof typeof TEMPLATES;\n packageManager: string;\n cwd: string;\n },\n) {\n const createSpinner = spinner(\n `Creating a new project from template. This may take a few minutes.`,\n ).start();\n\n const TEMPLATE_TAR_SUBPATH: Record<keyof typeof TEMPLATES, string> = {\n astro: \"ui-main/templates/astro\",\n \"astro-monorepo\": \"ui-main/templates/monorepo-astro\",\n \"astro-with-component-docs-monorepo\":\n \"ui-main/templates/monorepo-astro-with-docs\",\n };\n\n try {\n // Load local .env if present to allow GITHUB_TOKEN/GH_TOKEN\n dotenv.config({ quiet: true });\n const templatePath = path.join(\n os.tmpdir(),\n `bejamas-template-${Date.now()}`,\n );\n await fs.ensureDir(templatePath);\n\n // Auth via environment variables (.env supported)\n const authToken = process.env.GITHUB_TOKEN || process.env.GH_TOKEN;\n const usedAuth = Boolean(authToken);\n const headers: Record<string, string> = {\n \"User-Agent\": \"bejamas-cli\",\n };\n if (authToken) {\n headers[\"Authorization\"] = `Bearer ${authToken}`;\n }\n\n const response = await fetch(MONOREPO_TEMPLATE_URL, { headers });\n if (!response.ok) {\n if (\n response.status === 401 ||\n response.status === 403 ||\n (!usedAuth && response.status === 404)\n ) {\n throw new Error(\n \"Unauthorized to access private template. Set GITHUB_TOKEN or GH_TOKEN (in .env or env) with repo access and try again.\",\n );\n }\n if (response.status === 404) {\n throw new Error(\"Failed to download template: not found.\");\n }\n throw new Error(\n `Failed to download template: ${response.status} ${response.statusText}`,\n );\n }\n\n const tarPath = path.resolve(templatePath, \"template.tar.gz\");\n await fs.writeFile(tarPath, Buffer.from(await response.arrayBuffer()));\n\n const tarSubpath = TEMPLATE_TAR_SUBPATH[options.templateKey];\n const leafName = tarSubpath.split(\"/\").pop() as string;\n\n await execa(\"tar\", [\n \"-xzf\",\n tarPath,\n \"-C\",\n templatePath,\n \"--strip-components=2\",\n tarSubpath,\n ]);\n\n const extractedPath = path.resolve(templatePath, leafName);\n await fs.move(extractedPath, projectPath);\n await fs.remove(templatePath);\n\n await execa(options.packageManager, [\"install\"], {\n cwd: projectPath,\n });\n\n try {\n // Detect if we're inside an existing git repo; if yes, skip initializing a nested repo\n const { stdout } = await execa(\n \"git\",\n [\"rev-parse\", \"--is-inside-work-tree\"],\n { cwd: projectPath },\n );\n const insideExistingRepo = stdout.trim() === \"true\";\n\n if (!insideExistingRepo) {\n await execa(\"git\", [\"init\"], { cwd: projectPath });\n await execa(\"git\", [\"add\", \"-A\"], { cwd: projectPath });\n await execa(\"git\", [\"commit\", \"-m\", \"Initial commit\"], {\n cwd: projectPath,\n });\n }\n } catch (_) {\n // ignore git detection/initialization failures\n }\n\n createSpinner?.succeed(\"Creating a new project from template.\");\n } catch (error) {\n createSpinner?.fail(\n \"Something went wrong creating a new project from template.\",\n );\n handleError(error);\n }\n}\n","import { promises as fs } from \"fs\";\nimport path from \"path\";\nimport { preFlightInit } from \"@/src/preflights/preflight-init\";\n\nimport { BASE_COLORS, BUILTIN_REGISTRIES } from \"@/src/registry/constants\";\nimport { clearRegistryContext } from \"@/src/registry/context\";\n\nimport { TEMPLATES, createProject } from \"@/src/utils/create-project\";\nimport * as ERRORS from \"@/src/utils/errors\";\nimport { getConfig, createConfig, type Config } from \"@/src/utils/get-config\";\nimport { getProjectConfig, getProjectInfo } from \"@/src/utils/get-project-info\";\nimport { getPackageRunner } from \"@/src/utils/get-package-manager\";\nimport { handleError } from \"@/src/utils/handle-error\";\nimport { highlighter } from \"@/src/utils/highlighter\";\nimport { logger } from \"@/src/utils/logger\";\nimport { Command } from \"commander\";\nimport { execa } from \"execa\";\nimport fsExtra from \"fs-extra\";\nimport { z } from \"zod\";\n\n// process.on(\"exit\", (code) => {\n// const filePath = path.resolve(process.cwd(), \"components.json\")\n\n// // Delete backup if successful.\n// if (code === 0) {\n// return deleteFileBackup(filePath)\n// }\n\n// // Restore backup if error.\n// return restoreFileBackup(filePath)\n// })\n\n// Default fallback registry endpoint for shadcn (expects /r)\nconst DEFAULT_REGISTRY_URL = \"https://ui.bejamas.com/r\";\n\nexport const initOptionsSchema = z.object({\n cwd: z.string(),\n components: z.array(z.string()).optional(),\n yes: z.boolean(),\n defaults: z.boolean(),\n force: z.boolean(),\n silent: z.boolean(),\n isNewProject: z.boolean(),\n srcDir: z.boolean().optional(),\n cssVariables: z.boolean(),\n template: z\n .string()\n .optional()\n .refine(\n (val) => {\n if (val) {\n return TEMPLATES[val as keyof typeof TEMPLATES];\n }\n return true;\n },\n {\n message: \"Invalid template. Please use 'next' or 'next-monorepo'.\",\n },\n ),\n baseColor: z\n .string()\n .optional()\n .refine(\n (val) => {\n if (val) {\n return BASE_COLORS.find((color) => color.name === val);\n }\n\n return true;\n },\n {\n message: `Invalid base color. Please use '${BASE_COLORS.map(\n (color) => color.name,\n ).join(\"', '\")}'`,\n },\n ),\n baseStyle: z.boolean(),\n});\n\nexport const init = new Command()\n .name(\"init\")\n .description(\"initialize your project and install dependencies\")\n .argument(\"[components...]\", \"names, url or local path to component\")\n .option(\n \"-t, --template <template>\",\n \"the template to use. (next, next-monorepo)\",\n )\n .option(\n \"-b, --base-color <base-color>\",\n \"the base color to use. (neutral, gray, zinc, stone, slate)\",\n undefined,\n )\n .option(\"-y, --yes\", \"skip confirmation prompt.\", true)\n .option(\"-d, --defaults,\", \"use default configuration.\", false)\n .option(\"-f, --force\", \"force overwrite of existing configuration.\", false)\n .option(\n \"-c, --cwd <cwd>\",\n \"the working directory. defaults to the current directory.\",\n process.cwd(),\n )\n .option(\"-s, --silent\", \"mute output.\", false)\n .option(\n \"--src-dir\",\n \"use the src directory when creating a new project.\",\n false,\n )\n .option(\n \"--no-src-dir\",\n \"do not use the src directory when creating a new project.\",\n )\n .option(\"--css-variables\", \"use css variables for theming.\", true)\n .option(\"--no-css-variables\", \"do not use css variables for theming.\")\n .option(\"--no-base-style\", \"do not install the base shadcn style.\")\n .action(async (_components, opts) => {\n try {\n await runInit(opts);\n } catch (error) {\n logger.break();\n handleError(error);\n } finally {\n clearRegistryContext();\n }\n });\n\nexport async function runInit(\n options: z.infer<typeof initOptionsSchema> & {\n skipPreflight?: boolean;\n },\n) {\n let projectInfo;\n let newProjectTemplate;\n if (!options.skipPreflight) {\n const preflight = await preFlightInit(options);\n\n if (preflight.errors[ERRORS.MISSING_DIR_OR_EMPTY_PROJECT]) {\n const { projectPath, template } = await createProject(options);\n if (!projectPath) {\n process.exit(1);\n }\n options.cwd = projectPath;\n options.isNewProject = true;\n newProjectTemplate = template;\n }\n projectInfo = preflight.projectInfo;\n } else {\n projectInfo = await getProjectInfo(options.cwd);\n }\n\n if (newProjectTemplate) {\n const projectPath = {\n \"astro-monorepo\": \"apps/web\",\n \"astro-with-component-docs-monorepo\": \"apps/web\",\n astro: \"\",\n } as const;\n options.cwd = path.resolve(options.cwd, projectPath[newProjectTemplate]);\n\n logger.log(\n `${highlighter.success(\n \"Success!\",\n )} Project initialization completed.\\nYou may now add components.`,\n );\n\n return await getConfig(options.cwd);\n }\n\n // const projectConfig = await getProjectConfig(options.cwd, projectInfo);\n\n const shadcnBin = process.platform === \"win32\" ? \"shadcn.cmd\" : \"shadcn\";\n const localShadcnPath = path.resolve(\n options.cwd,\n \"node_modules\",\n \".bin\",\n shadcnBin,\n );\n\n try {\n const env = {\n ...process.env,\n REGISTRY_URL: process.env.REGISTRY_URL || DEFAULT_REGISTRY_URL,\n };\n if (await fsExtra.pathExists(localShadcnPath)) {\n await execa(localShadcnPath, [\"init\", \"--base-color\", \"neutral\"], {\n stdio: \"inherit\",\n cwd: options.cwd,\n env,\n });\n } else {\n // Follow user's runner preference (npx, bunx, pnpm dlx)\n await execa(\n \"npx\",\n [\"-y\", \"shadcn@latest\", \"init\", \"--base-color\", \"neutral\"],\n {\n stdio: \"inherit\",\n cwd: options.cwd,\n env,\n },\n );\n }\n } catch (err) {\n // shadcn already printed the detailed error to stdio, avoid double-reporting\n process.exit(1);\n }\n}\n","import { resolve } from \"node:path\";\nimport { existsSync, readFileSync } from \"node:fs\";\n\n/**\n * Read and parse tsconfig.json from the project root\n */\nexport function readTsConfig(projectRoot: string): any | null {\n try {\n const tsconfigPath = resolve(projectRoot, \"tsconfig.json\");\n if (!existsSync(tsconfigPath)) return null;\n const raw = readFileSync(tsconfigPath, \"utf-8\");\n return JSON.parse(raw);\n } catch {\n return null;\n }\n}\n\n/**\n * Resolve an alias path (like @/components) using tsconfig.json paths\n */\nexport function resolveAliasPathUsingTsConfig(\n inputPath: string,\n projectRoot: string,\n): string | null {\n const cfg = readTsConfig(projectRoot);\n if (!cfg || !cfg.compilerOptions) return null;\n const baseUrl: string = cfg.compilerOptions.baseUrl || \".\";\n const paths: Record<string, string[] | string> =\n cfg.compilerOptions.paths || {};\n for (const [key, values] of Object.entries(paths)) {\n const pattern = key.replace(/\\*/g, \"(.*)\");\n const re = new RegExp(`^${pattern}$`);\n const match = inputPath.match(re);\n if (!match) continue;\n const wildcard = match[1] || \"\";\n const first = Array.isArray(values) ? values[0] : values;\n if (!first) continue;\n const target = String(first).replace(/\\*/g, wildcard);\n return resolve(projectRoot, baseUrl, target);\n }\n return null;\n}\n","import { Command } from \"commander\";\nimport { resolve, isAbsolute, relative } from \"node:path\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { logger } from \"@/src/utils/logger\";\nimport { resolveAliasPathUsingTsConfig } from \"@/src/utils/tsconfig-utils\";\nimport prompts from \"prompts\";\n\nasync function generateDocs({\n cwd,\n outDir,\n verbose,\n}: {\n cwd?: string;\n outDir?: string;\n verbose?: boolean;\n}) {\n const DEBUG =\n process.env.BEJAMAS_DEBUG === \"1\" ||\n process.env.BEJAMAS_DEBUG === \"true\" ||\n verbose;\n\n try {\n const shellCwd = process.cwd();\n\n // Probe for components.json up the directory tree starting from shell CWD\n let projectRoot = shellCwd;\n let probe: string | null = shellCwd;\n for (let i = 0; i < 6 && probe; i += 1) {\n const candidate = resolve(probe, \"components.json\");\n if (existsSync(candidate)) {\n projectRoot = probe;\n try {\n const raw = readFileSync(candidate, \"utf-8\");\n const config = JSON.parse(raw);\n // If UI root not provided via CLI, try to infer from aliases.ui first\n if (!cwd && !process.env.BEJAMAS_UI_ROOT && config?.aliases?.ui) {\n const mapped: string = String(config.aliases.ui);\n let uiAbs: string | null = null;\n if (\n mapped.startsWith(\"./\") ||\n mapped.startsWith(\"../\") ||\n isAbsolute(mapped)\n ) {\n uiAbs = resolve(projectRoot, mapped);\n } else {\n uiAbs = resolveAliasPathUsingTsConfig(mapped, projectRoot);\n }\n if (!uiAbs && mapped.startsWith(\"@/\")) {\n uiAbs = resolve(projectRoot, \"src\", mapped.slice(2));\n }\n if (uiAbs) {\n process.env.BEJAMAS_UI_ROOT = uiAbs;\n }\n }\n // Fallback: infer UI root from tailwind.css\n if (!cwd && !process.env.BEJAMAS_UI_ROOT && config?.tailwind?.css) {\n const cssRaw = String(config.tailwind.css);\n let cssAbs: string | null = null;\n if (\n cssRaw.startsWith(\"./\") ||\n cssRaw.startsWith(\"../\") ||\n isAbsolute(cssRaw)\n ) {\n cssAbs = resolve(projectRoot, cssRaw);\n } else {\n cssAbs = resolveAliasPathUsingTsConfig(cssRaw, projectRoot);\n }\n if (!cssAbs && cssRaw.startsWith(\"@/\")) {\n cssAbs = resolve(projectRoot, \"src\", cssRaw.slice(2));\n }\n if (cssAbs) {\n const uiRootFromCss = resolve(cssAbs, \"..\", \"..\", \"..\");\n process.env.BEJAMAS_UI_ROOT = uiRootFromCss;\n }\n }\n // If out dir not provided via CLI, try to infer from aliases.docs\n if (!outDir && config?.aliases?.docs) {\n const mapped: string = String(config.aliases.docs);\n let outResolved: string | null = null;\n if (\n mapped.startsWith(\"./\") ||\n mapped.startsWith(\"../\") ||\n isAbsolute(mapped)\n ) {\n outResolved = mapped;\n } else {\n const abs = resolveAliasPathUsingTsConfig(mapped, projectRoot);\n if (abs) outResolved = relative(projectRoot, abs);\n }\n if (!outResolved && mapped.startsWith(\"@/\")) {\n outResolved = mapped.replace(/^@\\//, \"src/\");\n }\n // As a last resort, use the mapped value as-is so we do not prompt for output\n const finalOut = outResolved ?? mapped;\n if (finalOut && !process.env.BEJAMAS_DOCS_OUT_DIR) {\n process.env.BEJAMAS_DOCS_OUT_DIR = finalOut;\n process.env.BEJAMAS_DOCS_CWD = projectRoot;\n }\n }\n } catch {}\n break;\n }\n const parent = resolve(probe, \"..\");\n probe = parent === probe ? null : parent;\n }\n\n // Defaults if not already set from components.json\n if (!process.env.BEJAMAS_DOCS_CWD) {\n process.env.BEJAMAS_DOCS_CWD = shellCwd;\n }\n if (!process.env.BEJAMAS_UI_ROOT) {\n // Ask user for @bejamas/ui root when not inferred\n const defaultGuess = (() => {\n // Try local monorepo style packages/ui\n let current = shellCwd;\n for (let i = 0; i < 6; i += 1) {\n const cand = resolve(current, \"packages/ui/package.json\");\n if (existsSync(cand)) {\n const abs = resolve(current, \"packages/ui\");\n const rel = relative(shellCwd, abs);\n return rel || abs;\n }\n const parent = resolve(current, \"..\");\n if (parent === current) break;\n current = parent;\n }\n // Try installed node_modules fallback\n const nm = resolve(shellCwd, \"node_modules/@bejamas/ui/package.json\");\n if (existsSync(nm)) {\n const abs = resolve(shellCwd, \"node_modules/@bejamas/ui\");\n const rel = relative(shellCwd, abs);\n return rel || abs;\n }\n // Last resort: suggest a common local path\n return \"packages/ui\";\n })();\n const { uiRoot } = await prompts({\n type: \"text\",\n name: \"uiRoot\",\n message: \"Path to @bejamas/ui package root:\",\n initial: defaultGuess,\n validate: (val: string) => {\n const p = resolve(shellCwd, val);\n return existsSync(resolve(p, \"package.json\"))\n ? true\n : `No package.json found in ${p}`;\n },\n });\n if (!uiRoot) {\n logger.error(\"@bejamas/ui root is required to generate docs.\");\n process.exit(1);\n }\n process.env.BEJAMAS_UI_ROOT = resolve(shellCwd, uiRoot);\n }\n\n // CLI overrides take precedence\n if (cwd && cwd.length) {\n process.env.BEJAMAS_UI_ROOT = resolve(cwd);\n }\n if (outDir && outDir.length) {\n // Pass through exactly as provided; the generator will resolve against BEJAMAS_DOCS_CWD if needed.\n process.env.BEJAMAS_DOCS_OUT_DIR = outDir;\n }\n\n // If output dir still not defined, prompt the user\n if (!process.env.BEJAMAS_DOCS_OUT_DIR) {\n const { out } = await prompts({\n type: \"text\",\n name: \"out\",\n message: \"Where should we output docs (relative to project root)?\",\n initial: \"src/content/docs/components\",\n });\n if (!out) {\n logger.error(\"An output directory is required to generate docs.\");\n process.exit(1);\n }\n process.env.BEJAMAS_DOCS_OUT_DIR = out;\n process.env.BEJAMAS_DOCS_CWD = process.env.BEJAMAS_DOCS_CWD || shellCwd;\n }\n // Ensure the generator does not auto-run upon import; we'll invoke it explicitly\n process.env.BEJAMAS_SKIP_AUTO_RUN = \"1\";\n logger.info(`Generating docs...`);\n if (DEBUG) {\n logger.info(`Generator entry: @/src/docs/generate-mdx/index`);\n if (process.env.BEJAMAS_UI_ROOT)\n logger.info(`UI root: ${process.env.BEJAMAS_UI_ROOT}`);\n if (process.env.BEJAMAS_DOCS_CWD)\n logger.info(`Docs CWD: ${process.env.BEJAMAS_DOCS_CWD}`);\n if (process.env.BEJAMAS_DOCS_OUT_DIR)\n logger.info(`Docs out: ${process.env.BEJAMAS_DOCS_OUT_DIR}`);\n }\n const mod = await import(\"@/src/docs/generate-mdx/index\");\n if (typeof mod.runDocsGenerator === \"function\") {\n await mod.runDocsGenerator();\n } else {\n throw new Error(\n \"Failed to load docs generator. Export 'runDocsGenerator' not found.\",\n );\n }\n } catch (err: any) {\n logger.error(err?.message || String(err));\n process.exit(1);\n }\n}\n\nexport const docs = new Command()\n .name(\"docs:build\")\n .alias(\"docs\")\n .description(\"generate docs from @bejamas/ui components\")\n .option(\"-c, --cwd <cwd>\", \"path to UI working directory\")\n .option(\"-o, --out <outDir>\", \"output directory for generated MDX files\")\n .action(async (opts) => {\n await generateDocs({\n cwd: opts.cwd,\n outDir: opts.out,\n verbose: Boolean(opts.verbose),\n });\n });\n","import { Command } from \"commander\";\nimport { resolve, isAbsolute, join, extname } from \"node:path\";\nimport { existsSync, readFileSync, readdirSync } from \"node:fs\";\nimport {\n cyan,\n green,\n red,\n yellow,\n dim,\n bold,\n magenta,\n white,\n} from \"kleur/colors\";\nimport { logger } from \"@/src/utils/logger\";\nimport { resolveAliasPathUsingTsConfig } from \"@/src/utils/tsconfig-utils\";\nimport {\n extractFrontmatter,\n parseJsDocMetadata,\n resolveUiRoot,\n} from \"@/src/docs/generate-mdx/utils\";\n\ninterface ComponentDocStatus {\n name: string;\n file: string;\n status: \"complete\" | \"incomplete\" | \"missing\";\n missingRequired: string[];\n missingRecommended: string[];\n}\n\ninterface CheckResult {\n total: number;\n complete: ComponentDocStatus[];\n incomplete: ComponentDocStatus[];\n missing: ComponentDocStatus[];\n}\n\nconst REQUIRED_FIELDS = [\"name\", \"title\", \"description\"] as const;\nconst RECOMMENDED_FIELDS = [\n \"primaryExampleMDX\",\n \"usageMDX\",\n \"figmaUrl\",\n] as const;\n\nconst FIELD_LABELS: Record<string, string> = {\n name: \"@component\",\n title: \"@title\",\n description: \"@description\",\n primaryExampleMDX: \"@preview\",\n usageMDX: \"@usage\",\n figmaUrl: \"@figmaUrl\",\n};\n\nfunction checkComponentDocs(\n filePath: string,\n fileName: string,\n): ComponentDocStatus {\n const content = readFileSync(filePath, \"utf-8\");\n const frontmatter = extractFrontmatter(content);\n const meta = parseJsDocMetadata(frontmatter);\n\n const componentName = fileName.replace(/\\.astro$/i, \"\");\n const missingRequired: string[] = [];\n const missingRecommended: string[] = [];\n\n for (const field of REQUIRED_FIELDS) {\n const value = meta[field];\n if (!value || (typeof value === \"string\" && !value.trim())) {\n missingRequired.push(FIELD_LABELS[field] || field);\n }\n }\n\n for (const field of RECOMMENDED_FIELDS) {\n const value = meta[field];\n if (!value || (typeof value === \"string\" && !value.trim())) {\n missingRecommended.push(FIELD_LABELS[field] || field);\n }\n }\n\n let status: \"complete\" | \"incomplete\" | \"missing\";\n if (missingRequired.length > 0) {\n status = \"missing\";\n } else if (missingRecommended.length > 0) {\n status = \"incomplete\";\n } else {\n status = \"complete\";\n }\n\n return {\n name: componentName,\n file: fileName,\n status,\n missingRequired,\n missingRecommended,\n };\n}\n\nasync function checkDocs({\n cwd,\n json,\n}: {\n cwd?: string;\n json?: boolean;\n}): Promise<void> {\n try {\n const shellCwd = process.cwd();\n\n // Probe for components.json up the directory tree starting from shell CWD\n let projectRoot = shellCwd;\n let probe: string | null = shellCwd;\n for (let i = 0; i < 6 && probe; i += 1) {\n const candidate = resolve(probe, \"components.json\");\n if (existsSync(candidate)) {\n projectRoot = probe;\n try {\n const raw = readFileSync(candidate, \"utf-8\");\n const config = JSON.parse(raw);\n // If UI root not provided via CLI, try to infer from aliases.ui first\n if (!cwd && !process.env.BEJAMAS_UI_ROOT && config?.aliases?.ui) {\n const mapped: string = String(config.aliases.ui);\n let uiAbs: string | null = null;\n if (\n mapped.startsWith(\"./\") ||\n mapped.startsWith(\"../\") ||\n isAbsolute(mapped)\n ) {\n uiAbs = resolve(projectRoot, mapped);\n } else {\n uiAbs = resolveAliasPathUsingTsConfig(mapped, projectRoot);\n }\n if (!uiAbs && mapped.startsWith(\"@/\")) {\n uiAbs = resolve(projectRoot, \"src\", mapped.slice(2));\n }\n if (uiAbs) {\n process.env.BEJAMAS_UI_ROOT = uiAbs;\n }\n }\n // Fallback: infer UI root from tailwind.css\n if (!cwd && !process.env.BEJAMAS_UI_ROOT && config?.tailwind?.css) {\n const cssRaw = String(config.tailwind.css);\n let cssAbs: string | null = null;\n if (\n cssRaw.startsWith(\"./\") ||\n cssRaw.startsWith(\"../\") ||\n isAbsolute(cssRaw)\n ) {\n cssAbs = resolve(projectRoot, cssRaw);\n } else {\n cssAbs = resolveAliasPathUsingTsConfig(cssRaw, projectRoot);\n }\n if (!cssAbs && cssRaw.startsWith(\"@/\")) {\n cssAbs = resolve(projectRoot, \"src\", cssRaw.slice(2));\n }\n if (cssAbs) {\n const uiRootFromCss = resolve(cssAbs, \"..\", \"..\", \"..\");\n process.env.BEJAMAS_UI_ROOT = uiRootFromCss;\n }\n }\n } catch {}\n break;\n }\n const parent = resolve(probe, \"..\");\n probe = parent === probe ? null : parent;\n }\n\n // CLI override takes precedence\n if (cwd && cwd.length) {\n process.env.BEJAMAS_UI_ROOT = resolve(cwd);\n }\n\n let uiRoot: string;\n try {\n uiRoot = resolveUiRoot(shellCwd);\n } catch {\n logger.error(\n \"Unable to locate @bejamas/ui. Use --cwd to specify the UI package path.\",\n );\n process.exit(1);\n }\n\n const componentsDir = join(uiRoot, \"src\", \"components\");\n if (!existsSync(componentsDir)) {\n logger.error(\n `Components directory not found: ${componentsDir}\\n\\n` +\n `Expected structure: <uiRoot>/src/components/*.astro\\n` +\n `Use --cwd to specify a different UI package root.`,\n );\n process.exit(1);\n }\n\n const files = readdirSync(componentsDir, { withFileTypes: true })\n .filter((e) => e.isFile() && extname(e.name).toLowerCase() === \".astro\")\n .map((e) => e.name)\n .sort();\n\n if (files.length === 0) {\n logger.warn(\"No .astro component files found.\");\n process.exit(0);\n }\n\n const results: ComponentDocStatus[] = [];\n for (const file of files) {\n const filePath = join(componentsDir, file);\n const status = checkComponentDocs(filePath, file);\n results.push(status);\n }\n\n const complete = results.filter((r) => r.status === \"complete\");\n const incomplete = results.filter((r) => r.status === \"incomplete\");\n const missing = results.filter((r) => r.status === \"missing\");\n\n const checkResult: CheckResult = {\n total: results.length,\n complete,\n incomplete,\n missing,\n };\n\n if (json) {\n console.log(JSON.stringify(checkResult, null, 2));\n // Exit with error code if there are components missing required docs\n if (missing.length > 0) {\n process.exit(1);\n }\n return;\n }\n\n // Print formatted report\n const termWidth = Math.min(80, process.stdout.columns || 80);\n const headerLine = \"━\".repeat(termWidth);\n\n logger.break();\n console.log(dim(\"┌\" + \"─\".repeat(termWidth - 2) + \"┐\"));\n console.log(\n dim(\"│\") +\n bold(cyan(\" docs:check\")) +\n dim(\" — Component Documentation Status\") +\n \" \".repeat(Math.max(0, termWidth - 47)) +\n dim(\"│\"),\n );\n console.log(dim(\"└\" + \"─\".repeat(termWidth - 2) + \"┘\"));\n logger.break();\n\n // Helper to format tags with color\n const formatTag = (tag: string) => magenta(tag);\n const formatComponentName = (name: string) => bold(white(name));\n\n // Complete components\n if (complete.length > 0) {\n console.log(\n green(\n `✓ Complete (${complete.length} component${complete.length === 1 ? \"\" : \"s\"}):`,\n ),\n );\n const names = complete\n .map((c) => formatComponentName(c.name))\n .join(dim(\", \"));\n console.log(` ${names}`);\n logger.break();\n }\n\n // Incomplete components (missing recommended fields)\n if (incomplete.length > 0) {\n console.log(\n yellow(\n `⚠ Incomplete (${incomplete.length} component${incomplete.length === 1 ? \"\" : \"s\"}):`,\n ),\n );\n for (const comp of incomplete) {\n const missingFields = comp.missingRecommended\n .map(formatTag)\n .join(dim(\", \"));\n console.log(\n ` ${formatComponentName(comp.name)} ${dim(\"-\")} ${dim(\"missing:\")} ${missingFields}`,\n );\n }\n logger.break();\n }\n\n // Missing docs (missing required fields)\n if (missing.length > 0) {\n console.log(\n red(\n `✗ Missing Docs (${missing.length} component${missing.length === 1 ? \"\" : \"s\"}):`,\n ),\n );\n for (const comp of missing) {\n const missingFields = comp.missingRequired\n .map(formatTag)\n .join(dim(\", \"));\n console.log(\n ` ${formatComponentName(comp.name)} ${dim(\"-\")} ${dim(\"missing:\")} ${missingFields}`,\n );\n }\n logger.break();\n }\n\n // Summary\n console.log(dim(headerLine));\n const completeText = green(`${complete.length}/${results.length} complete`);\n const incompleteText =\n incomplete.length > 0\n ? yellow(`${incomplete.length} incomplete`)\n : dim(`${incomplete.length} incomplete`);\n const missingText =\n missing.length > 0\n ? red(`${missing.length} missing docs`)\n : dim(`${missing.length} missing docs`);\n console.log(\n `${bold(\"Summary:\")} ${completeText} ${dim(\"|\")} ${incompleteText} ${dim(\"|\")} ${missingText}`,\n );\n logger.break();\n\n // Exit with error code if there are components missing required docs\n if (missing.length > 0) {\n process.exit(1);\n }\n } catch (err: any) {\n logger.error(err?.message || String(err));\n process.exit(1);\n }\n}\n\nexport const docsCheck = new Command()\n .name(\"docs:check\")\n .description(\"check documentation status for all components\")\n .option(\"-c, --cwd <cwd>\", \"path to UI working directory\")\n .option(\"--json\", \"output results as JSON\")\n .action(async (opts) => {\n await checkDocs({\n cwd: opts.cwd,\n json: Boolean(opts.json),\n });\n });\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport fg from \"fast-glob\";\nimport { logger } from \"@/src/utils/logger\";\nimport { Config, getConfig } from \"@/src/utils/get-config\";\n\nexport function updateImportAliases(\n moduleSpecifier: string,\n config: Config,\n isRemote: boolean = false,\n) {\n // Not a local import.\n if (!moduleSpecifier.startsWith(\"@/\") && !isRemote) {\n return moduleSpecifier;\n }\n\n // This treats the remote as coming from a faux registry.\n let specifier = moduleSpecifier;\n if (isRemote && specifier.startsWith(\"@/\")) {\n specifier = specifier.replace(/^@\\//, \"@/registry/new-york/\");\n }\n\n // Not a registry import.\n if (!specifier.startsWith(\"@/registry/\")) {\n // We fix the alias and return.\n const alias = config.aliases.components.split(\"/\")[0];\n return specifier.replace(/^@\\//, `${alias}/`);\n }\n\n if (specifier.match(/^@\\/registry\\/(.+)\\/ui/)) {\n return specifier.replace(\n /^@\\/registry\\/(.+)\\/ui/,\n config.aliases.ui ?? `${config.aliases.components}/ui`,\n );\n }\n\n if (\n config.aliases.components &&\n specifier.match(/^@\\/registry\\/(.+)\\/components/)\n ) {\n return specifier.replace(\n /^@\\/registry\\/(.+)\\/components/,\n config.aliases.components,\n );\n }\n\n if (config.aliases.lib && specifier.match(/^@\\/registry\\/(.+)\\/lib/)) {\n return specifier.replace(/^@\\/registry\\/(.+)\\/lib/, config.aliases.lib);\n }\n\n if (config.aliases.hooks && specifier.match(/^@\\/registry\\/(.+)\\/hooks/)) {\n return specifier.replace(/^@\\/registry\\/(.+)\\/hooks/, config.aliases.hooks);\n }\n\n return specifier.replace(/^@\\/registry\\/[^/]+/, config.aliases.components);\n}\n\nexport function rewriteAstroImports(content: string, config: Config) {\n let updated = content;\n\n const utilsAlias = config.aliases?.utils;\n const workspaceAlias =\n typeof utilsAlias === \"string\" && utilsAlias.includes(\"/\")\n ? utilsAlias.split(\"/\")[0]\n : \"@\";\n const utilsImport = `${workspaceAlias}/lib/utils`;\n\n // Handle standard imports with specifiers, e.g. `import { x } from \"path\"`\n updated = updated.replace(\n /import\\s+([\\s\\S]*?)\\s+from\\s+[\"']([^\"']+)[\"']/g,\n (full, importsPart, specifier) => {\n const next = updateImportAliases(specifier, config, false);\n\n let finalSpec = next;\n const includesCn =\n typeof importsPart === \"string\" &&\n importsPart.split(/[{},\\s]/).some((part: string) => part === \"cn\");\n\n if (\n includesCn &&\n config.aliases.utils &&\n (next === utilsImport || next === \"@/lib/utils\")\n ) {\n finalSpec =\n utilsImport === next\n ? next.replace(utilsImport, config.aliases.utils)\n : config.aliases.utils;\n }\n\n if (finalSpec === specifier) return full;\n return full.replace(specifier, finalSpec);\n },\n );\n\n // Handle bare imports, e.g. `import \"path\"`\n updated = updated.replace(/import\\s+[\"']([^\"']+)[\"']/g, (full, specifier) => {\n const next = updateImportAliases(specifier, config, false);\n if (next === specifier) return full;\n return full.replace(specifier, next);\n });\n\n return updated;\n}\n\nexport async function fixAstroImports(cwd: string, isVerbose: boolean) {\n const config = await getConfig(cwd);\n if (!config) return;\n\n const searchRoots = new Set<string>([\n config.resolvedPaths.components,\n config.resolvedPaths.ui,\n ]);\n\n for (const root of Array.from(searchRoots)) {\n if (!root) continue;\n const astroFiles = await fg(\"**/*.astro\", {\n cwd: root,\n absolute: true,\n dot: false,\n });\n\n for (const filePath of astroFiles) {\n const original = await fs.readFile(filePath, \"utf8\");\n const rewritten = rewriteAstroImports(original, config);\n if (rewritten === original) continue;\n await fs.writeFile(filePath, rewritten, \"utf8\");\n if (isVerbose) {\n logger.info(\n `[bejamas-ui] fixed imports in ${path.relative(cwd, filePath)}`,\n );\n }\n }\n }\n}\n\n","import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { logger } from \"@/src/utils/logger\";\n\nexport interface RegistryFile {\n path: string;\n content: string;\n type: string;\n target?: string;\n}\n\nexport interface RegistryItem {\n name: string;\n type: string;\n files: RegistryFile[];\n dependencies?: string[];\n devDependencies?: string[];\n registryDependencies?: string[];\n}\n\n/** Maps filename to subfolder/filename for path rewriting */\nexport type PathRewriteMap = Map<string, string>;\n\n/**\n * Fetches a registry item JSON from the registry URL.\n */\nexport async function fetchRegistryItem(\n componentName: string,\n registryUrl: string,\n): Promise<RegistryItem | null> {\n // Handle style-prefixed URLs (e.g., styles/new-york-v4/avatar.json)\n const url = `${registryUrl}/styles/new-york-v4/${componentName}.json`;\n\n try {\n const response = await fetch(url);\n if (!response.ok) {\n // Try without styles prefix as fallback\n const fallbackUrl = `${registryUrl}/${componentName}.json`;\n const fallbackResponse = await fetch(fallbackUrl);\n if (!fallbackResponse.ok) {\n return null;\n }\n return (await fallbackResponse.json()) as RegistryItem;\n }\n return (await response.json()) as RegistryItem;\n } catch {\n return null;\n }\n}\n\n/**\n * Extracts the subfolder name from registry file paths.\n * E.g., \"components/ui/avatar/Avatar.astro\" → \"avatar\"\n */\nexport function getSubfolderFromPaths(files: RegistryFile[]): string | null {\n // Only consider registry:ui files\n const uiFiles = files.filter((f) => f.type === \"registry:ui\");\n if (uiFiles.length < 2) {\n // Single file components don't need subfolders\n return null;\n }\n\n const subfolders = new Set<string>();\n\n for (const file of uiFiles) {\n const parts = file.path.split(\"/\");\n // Look for pattern: .../ui/<subfolder>/<filename>\n const uiIndex = parts.indexOf(\"ui\");\n if (uiIndex !== -1 && parts.length > uiIndex + 2) {\n // There's at least one folder after \"ui\" before the filename\n subfolders.add(parts[uiIndex + 1]);\n }\n }\n\n // If all files share the same subfolder, use it\n if (subfolders.size === 1) {\n return Array.from(subfolders)[0];\n }\n\n // Fallback: use the component name from the first file's parent directory\n if (uiFiles.length > 0) {\n const firstPath = uiFiles[0].path;\n const dirname = path.dirname(firstPath);\n const folderName = path.basename(dirname);\n // Only use if it's not \"ui\" itself\n if (folderName && folderName !== \"ui\") {\n return folderName;\n }\n }\n\n return null;\n}\n\n/**\n * Checks if a path exists.\n */\nasync function pathExists(filePath: string): Promise<boolean> {\n try {\n await fs.access(filePath);\n return true;\n } catch {\n return false;\n }\n}\n\n/**\n * Builds a map of path rewrites for components that will be reorganized.\n * Call this BEFORE shadcn runs to know how to rewrite output paths.\n */\nexport async function buildPathRewriteMap(\n components: string[],\n uiDir: string,\n registryUrl: string,\n): Promise<PathRewriteMap> {\n const rewrites: PathRewriteMap = new Map();\n\n if (!uiDir || components.length === 0) {\n return rewrites;\n }\n\n for (const componentName of components) {\n try {\n const registryItem = await fetchRegistryItem(componentName, registryUrl);\n if (!registryItem) continue;\n\n const subfolder = getSubfolderFromPaths(registryItem.files);\n if (!subfolder) continue;\n\n // Get the UI files that will be reorganized\n const uiFiles = registryItem.files.filter(\n (f) => f.type === \"registry:ui\",\n );\n\n for (const file of uiFiles) {\n const filename = path.basename(file.path);\n // Map: \"Avatar.astro\" → \"avatar/Avatar.astro\"\n rewrites.set(filename, `${subfolder}/${filename}`);\n }\n } catch {\n // Ignore errors, just skip this component\n }\n }\n\n return rewrites;\n}\n\n/**\n * Rewrites file paths in shadcn output to reflect reorganized structure.\n * Replaces flat paths like \"/ui/Avatar.astro\" with \"/ui/avatar/Avatar.astro\"\n */\nexport function rewriteOutputPaths(\n output: string,\n rewrites: PathRewriteMap,\n): string {\n let result = output;\n\n for (const [filename, newPath] of rewrites) {\n // Match paths ending with the filename (handles various path formats)\n // e.g., \"packages/ui/src/components/Avatar.astro\" → \"packages/ui/src/components/avatar/Avatar.astro\"\n const escapedFilename = filename.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const pattern = new RegExp(`(/[^/\\\\s]+)/${escapedFilename}(?=\\\\s|$|\\\\n)`, \"g\");\n result = result.replace(pattern, `$1/${newPath}`);\n }\n\n return result;\n}\n\nexport interface ReorganizeResult {\n totalMoved: number;\n movedFiles: string[]; // e.g., [\"avatar/Avatar.astro\", \"avatar/index.ts\"]\n skippedFiles: string[]; // Files that already existed in subfolder (flat duplicate removed)\n}\n\n/**\n * Reorganizes multi-file components into correct subfolders.\n * Only moves files from FLAT location to subfolder.\n * Does NOT touch files already in subfolders.\n * E.g., moves `uiDir/Avatar.astro` to `uiDir/avatar/Avatar.astro`.\n * Returns info about moved files for display purposes.\n */\nexport async function reorganizeComponents(\n components: string[],\n uiDir: string,\n registryUrl: string,\n verbose: boolean,\n): Promise<ReorganizeResult> {\n const result: ReorganizeResult = { totalMoved: 0, movedFiles: [], skippedFiles: [] };\n\n if (!uiDir || components.length === 0) {\n return result;\n }\n\n for (const componentName of components) {\n try {\n const registryItem = await fetchRegistryItem(componentName, registryUrl);\n if (!registryItem) {\n if (verbose) {\n logger.info(\n `[bejamas-ui] Could not fetch registry for ${componentName}, skipping reorganization`,\n );\n }\n continue;\n }\n\n const subfolder = getSubfolderFromPaths(registryItem.files);\n if (!subfolder) {\n // Single-file component or no subfolder detected, skip\n if (verbose) {\n logger.info(\n `[bejamas-ui] ${componentName} is single-file or has no subfolder, skipping`,\n );\n }\n continue;\n }\n\n // Get the UI files that need to be moved\n const uiFiles = registryItem.files.filter(\n (f) => f.type === \"registry:ui\",\n );\n\n const targetDir = path.join(uiDir, subfolder);\n let movedCount = 0;\n\n for (const file of uiFiles) {\n const filename = path.basename(file.path);\n // Only look for files in FLAT location (directly in uiDir)\n const flatPath = path.join(uiDir, filename);\n const targetPath = path.join(targetDir, filename);\n\n // Check if file exists in flat location\n if (!(await pathExists(flatPath))) {\n // Not in flat location, skip (may already be in subfolder)\n continue;\n }\n\n // Check if target already exists (don't overwrite, but clean up flat duplicate)\n if (await pathExists(targetPath)) {\n // Target exists in subfolder - delete the flat duplicate shadcn just created\n try {\n await fs.unlink(flatPath);\n result.skippedFiles.push(`${subfolder}/${filename}`);\n if (verbose) {\n logger.info(\n `[bejamas-ui] Removed flat duplicate: ${filename} (${subfolder}/${filename} exists)`,\n );\n }\n } catch {\n // Flat file might not exist or already deleted, but still counts as skipped\n result.skippedFiles.push(`${subfolder}/${filename}`);\n }\n continue;\n }\n\n // Create target directory if needed\n await fs.mkdir(targetDir, { recursive: true });\n\n // Move file from flat to subfolder\n await fs.rename(flatPath, targetPath);\n movedCount++;\n result.totalMoved++;\n result.movedFiles.push(`${subfolder}/${filename}`);\n\n if (verbose) {\n logger.info(`[bejamas-ui] Moved ${filename} → ${subfolder}/${filename}`);\n }\n }\n\n if (movedCount > 0 && verbose) {\n logger.info(\n `[bejamas-ui] Reorganized ${componentName} into ${subfolder}/`,\n );\n }\n } catch (err) {\n // Non-fatal: log and continue with other components\n if (verbose) {\n logger.warn(\n `[bejamas-ui] Failed to reorganize ${componentName}: ${err}`,\n );\n }\n }\n }\n\n return result;\n}\n\n","import path from \"node:path\";\nimport { Command } from \"commander\";\nimport { execa } from \"execa\";\nimport prompts from \"prompts\";\nimport { logger } from \"@/src/utils/logger\";\nimport { spinner } from \"@/src/utils/spinner\";\nimport { highlighter } from \"@/src/utils/highlighter\";\nimport { getPackageRunner } from \"@/src/utils/get-package-manager\";\nimport { fixAstroImports } from \"@/src/utils/astro-imports\";\nimport { getConfig, getWorkspaceConfig } from \"@/src/utils/get-config\";\nimport {\n reorganizeComponents,\n fetchRegistryItem,\n getSubfolderFromPaths,\n} from \"@/src/utils/reorganize-components\";\n\ninterface ParsedOutput {\n created: string[];\n updated: string[];\n skipped: string[];\n}\n\n// Default fallback registry endpoint for shadcn (expects /r)\nconst DEFAULT_REGISTRY_URL = \"https://ui.bejamas.com/r\";\n\n// Derive only the user-provided flags for shadcn to avoid losing options\nfunction extractOptionsForShadcn(rawArgv: string[], cmd: Command): string[] {\n // Prefer commander metadata when available so we only forward options that\n // were explicitly set (avoids defaults and keeps aliases consistent).\n if (typeof cmd.getOptionValueSource === \"function\") {\n const opts = cmd.optsWithGlobals() as Record<string, unknown>;\n const forwarded: string[] = [];\n const getSource = (key: string) => cmd.getOptionValueSource(key);\n\n const addBoolean = (key: string, flag: string, negateFlag?: string) => {\n if (getSource(key) !== \"cli\") return;\n const value = opts[key];\n if (typeof value !== \"boolean\") return;\n if (value) {\n forwarded.push(flag);\n } else if (negateFlag) {\n forwarded.push(negateFlag);\n }\n };\n\n const addString = (key: string, flag: string) => {\n if (getSource(key) !== \"cli\") return;\n const value = opts[key];\n if (typeof value === \"string\") {\n forwarded.push(flag, value);\n }\n };\n\n addBoolean(\"yes\", \"--yes\");\n addBoolean(\"overwrite\", \"--overwrite\");\n addString(\"cwd\", \"--cwd\");\n addBoolean(\"all\", \"--all\");\n addString(\"path\", \"--path\");\n addBoolean(\"silent\", \"--silent\");\n addBoolean(\"srcDir\", \"--src-dir\", \"--no-src-dir\");\n\n // Preserve any explicit passthrough after \"--\" for shadcn.\n const addIndex = rawArgv.findIndex((arg) => arg === \"add\");\n if (addIndex !== -1) {\n const rest = rawArgv.slice(addIndex + 1);\n const doubleDashIndex = rest.indexOf(\"--\");\n if (doubleDashIndex !== -1) {\n forwarded.push(...rest.slice(doubleDashIndex));\n }\n }\n\n return forwarded;\n }\n\n // Fallback: lightweight parser that only forwards known options.\n const addIndex = rawArgv.findIndex((arg) => arg === \"add\");\n if (addIndex === -1) return [];\n const rest = rawArgv.slice(addIndex + 1);\n const forwarded: string[] = [];\n const optionsWithValues = new Set([\"-c\", \"--cwd\", \"-p\", \"--path\"]);\n const filteredFlags = new Set([\"-v\", \"--verbose\"]);\n\n for (let i = 0; i < rest.length; i += 1) {\n const token = rest[i];\n if (token === \"--\") {\n forwarded.push(\"--\", ...rest.slice(i + 1));\n break;\n }\n if (!token.startsWith(\"-\")) continue;\n if (filteredFlags.has(token)) continue;\n\n forwarded.push(token);\n if (token.includes(\"=\")) continue;\n\n if (optionsWithValues.has(token)) {\n const next = rest[i + 1];\n if (next) {\n forwarded.push(next);\n i += 1;\n }\n }\n }\n return forwarded;\n}\n\ninterface ComponentFileInfo {\n subfolder: string;\n files: string[]; // All filenames for this component\n}\n\ninterface SubfolderMapResult {\n // Maps unique filename -> subfolder/filename\n uniqueMap: Map<string, string>;\n // Maps component subfolder -> all its files (for grouping)\n componentInfo: Map<string, ComponentFileInfo>;\n // Set of shared filenames (like index.ts) that appear in multiple components\n sharedFilenames: Set<string>;\n}\n\n/** Build maps for path rewriting, handling filename collisions */\nasync function buildSubfolderMap(\n components: string[],\n registryUrl: string,\n): Promise<SubfolderMapResult> {\n const filenameToSubfolders = new Map<string, string[]>();\n const componentInfo = new Map<string, ComponentFileInfo>();\n\n // First pass: collect all filename -> subfolder mappings\n for (const componentName of components) {\n const registryItem = await fetchRegistryItem(componentName, registryUrl);\n if (!registryItem) continue;\n\n const subfolder = getSubfolderFromPaths(registryItem.files);\n if (!subfolder) continue;\n\n const files: string[] = [];\n for (const file of registryItem.files) {\n if (file.type === \"registry:ui\") {\n const filename = path.basename(file.path);\n files.push(filename);\n\n // Track which subfolders each filename appears in\n const subfolders = filenameToSubfolders.get(filename) || [];\n subfolders.push(subfolder);\n filenameToSubfolders.set(filename, subfolders);\n }\n }\n\n componentInfo.set(subfolder, { subfolder, files });\n }\n\n // Build the unique map (only filenames that appear once)\n const uniqueMap = new Map<string, string>();\n const sharedFilenames = new Set<string>();\n\n filenameToSubfolders.forEach((subfolders, filename) => {\n if (subfolders.length === 1) {\n // Unique filename - safe to map directly\n uniqueMap.set(filename, `${subfolders[0]}/${filename}`);\n } else {\n // Shared filename (like index.ts) - track for context-based rewriting\n sharedFilenames.add(filename);\n }\n });\n\n return { uniqueMap, componentInfo, sharedFilenames };\n}\n\n/**\n * Rewrite file paths to include correct subfolders.\n * Handles shared filenames (like index.ts) by tracking current component context.\n */\nfunction rewritePaths(\n paths: string[],\n mapResult: SubfolderMapResult,\n): string[] {\n const { uniqueMap, componentInfo, sharedFilenames } = mapResult;\n let currentSubfolder: string | null = null;\n\n return paths.map((filePath) => {\n const filename = path.basename(filePath);\n const parentDir = path.basename(path.dirname(filePath));\n\n // Check if this is a unique filename (can map directly)\n const uniqueMapping = uniqueMap.get(filename);\n if (uniqueMapping) {\n const expectedSubfolder = path.dirname(uniqueMapping);\n\n // Update current context for subsequent shared files\n currentSubfolder = expectedSubfolder;\n\n // Only rewrite if not already in the correct subfolder\n if (parentDir !== expectedSubfolder) {\n const dir = path.dirname(filePath);\n return `${dir}/${uniqueMapping}`;\n }\n return filePath;\n }\n\n // Check if this is a shared filename (like index.ts)\n if (sharedFilenames.has(filename) && currentSubfolder) {\n // Use the current component context\n const expectedSubfolder = currentSubfolder;\n\n // Only rewrite if not already in the correct subfolder\n if (parentDir !== expectedSubfolder) {\n const dir = path.dirname(filePath);\n return `${dir}/${expectedSubfolder}/${filename}`;\n }\n }\n\n return filePath;\n });\n}\n\n/** Fetch available components from the registry */\nasync function fetchAvailableComponents(\n registryUrl: string,\n): Promise<{ name: string; type?: string }[]> {\n const indexUrl = `${registryUrl}/index.json`;\n const response = await fetch(indexUrl);\n if (!response.ok) {\n throw new Error(`Failed to fetch registry index: ${response.statusText}`);\n }\n const data = await response.json();\n // Registry index is an array of objects with at least a name property\n return Array.isArray(data) ? data : [];\n}\n\n/** Prompt user to select components interactively */\nasync function promptForComponents(\n registryUrl: string,\n): Promise<string[] | null> {\n const checkingSpinner = spinner(\"Checking registry.\").start();\n\n let components: { name: string; type?: string }[];\n try {\n components = await fetchAvailableComponents(registryUrl);\n checkingSpinner.succeed();\n } catch (error) {\n checkingSpinner.fail();\n logger.error(\"Failed to fetch available components from registry.\");\n return null;\n }\n\n if (components.length === 0) {\n logger.warn(\"No components available in registry.\");\n return null;\n }\n\n // Filter to only ui:* type components if type info is available\n const uiComponents = components.filter(\n (c) => !c.type || c.type === \"registry:ui\",\n );\n\n const choices = uiComponents.map((c) => ({\n title: c.name,\n value: c.name,\n }));\n\n const { selected } = await prompts({\n type: \"autocompleteMultiselect\",\n name: \"selected\",\n message: \"Which components would you like to add?\",\n choices,\n hint: \"- Space to select. Return to submit.\",\n instructions: false,\n });\n\n // User cancelled (Ctrl+C)\n if (!selected) {\n return null;\n }\n\n return selected;\n}\n\n/** Parse shadcn output to extract file lists (stdout has paths, stderr has headers) */\nfunction parseShadcnOutput(stdout: string, stderr: string): ParsedOutput {\n const result: ParsedOutput = { created: [], updated: [], skipped: [] };\n\n // Remove ANSI escape codes for parsing\n const cleanStderr = stderr.replace(/\\x1b\\[[0-9;]*m/g, \"\");\n const cleanStdout = stdout.replace(/\\x1b\\[[0-9;]*m/g, \"\");\n\n // Extract counts from stderr headers\n // Matches patterns like \"✔ Created 4 files:\" or \"ℹ Skipped 2 files:\"\n const createdMatch = cleanStderr.match(/Created\\s+(\\d+)\\s+file/i);\n const updatedMatch = cleanStderr.match(/Updated\\s+(\\d+)\\s+file/i);\n const skippedMatch = cleanStderr.match(/Skipped\\s+(\\d+)\\s+file/i);\n\n const createdCount = createdMatch ? parseInt(createdMatch[1], 10) : 0;\n const updatedCount = updatedMatch ? parseInt(updatedMatch[1], 10) : 0;\n const skippedCount = skippedMatch ? parseInt(skippedMatch[1], 10) : 0;\n\n // Extract file paths from stdout (lines starting with \" - \")\n const allPaths: string[] = [];\n for (const line of cleanStdout.split(\"\\n\")) {\n const match = line.match(/^\\s+-\\s+(.+)$/);\n if (match) {\n allPaths.push(match[1].trim());\n }\n }\n\n // Also check stderr for file paths (some shadcn versions output there)\n for (const line of cleanStderr.split(\"\\n\")) {\n const match = line.match(/^\\s+-\\s+(.+)$/);\n if (match) {\n const filePath = match[1].trim();\n // Avoid duplicates\n if (!allPaths.includes(filePath)) {\n allPaths.push(filePath);\n }\n }\n }\n\n // Assign paths to sections based on counts (order: created, updated, skipped)\n let idx = 0;\n for (let i = 0; i < createdCount && idx < allPaths.length; i++) {\n result.created.push(allPaths[idx++]);\n }\n for (let i = 0; i < updatedCount && idx < allPaths.length; i++) {\n result.updated.push(allPaths[idx++]);\n }\n for (let i = 0; i < skippedCount && idx < allPaths.length; i++) {\n result.skipped.push(allPaths[idx++]);\n }\n\n return result;\n}\n\nasync function addComponents(\n packages: string[],\n forwardedOptions: string[],\n isVerbose: boolean,\n isSilent: boolean,\n subfolderMapResult: SubfolderMapResult,\n): Promise<ParsedOutput> {\n const runner = await getPackageRunner(process.cwd());\n const env = {\n ...process.env,\n REGISTRY_URL: process.env.REGISTRY_URL || DEFAULT_REGISTRY_URL,\n };\n // Always pass --yes for non-interactive mode (skips \"Add components?\" confirmation)\n // Note: we don't pass --overwrite by default to respect user customizations\n const autoFlags: string[] = [];\n if (!forwardedOptions.includes(\"--yes\")) {\n autoFlags.push(\"--yes\");\n }\n const baseArgs = [\n \"shadcn@latest\",\n \"add\",\n ...packages,\n ...autoFlags,\n ...forwardedOptions,\n ];\n\n let cmd = \"npx\";\n let args: string[] = [\"-y\", ...baseArgs];\n if (runner === \"bunx\") {\n cmd = \"bunx\";\n args = baseArgs;\n } else if (runner === \"pnpm dlx\") {\n cmd = \"pnpm\";\n args = [\"dlx\", ...baseArgs];\n } else if (runner === \"npx\") {\n cmd = \"npx\";\n args = [\"-y\", ...baseArgs];\n }\n\n if (isVerbose) {\n logger.info(`[bejamas-ui] ${cmd} ${args.join(\" \")}`);\n }\n\n // Show our own spinner for checking registry\n const registrySpinner = spinner(\"Checking registry.\", { silent: isSilent });\n registrySpinner.start();\n\n try {\n // Run shadcn and capture output\n // Pipe \"n\" to stdin to answer \"no\" to any overwrite prompts (respects user customizations)\n const result = await execa(cmd, args, {\n env,\n input: \"n\\nn\\nn\\nn\\nn\\nn\\nn\\nn\\nn\\nn\\n\", // Answer \"no\" to up to 10 overwrite prompts\n stdout: \"pipe\",\n stderr: \"pipe\",\n reject: false,\n });\n\n registrySpinner.succeed();\n\n // Show installing spinner (already done at this point)\n const installSpinner = spinner(\"Installing components.\", {\n silent: isSilent,\n });\n installSpinner.succeed();\n\n // Parse the output to get file lists (stdout has paths, stderr has headers)\n const stdout = result.stdout || \"\";\n const stderr = result.stderr || \"\";\n\n if (isVerbose) {\n logger.info(`[bejamas-ui] Raw stdout: ${stdout}`);\n logger.info(`[bejamas-ui] Raw stderr: ${stderr}`);\n }\n\n const parsed = parseShadcnOutput(stdout, stderr);\n\n // Return parsed data - display is handled by caller after reorganization\n // This allows accurate reporting (shadcn says \"created\" but we may skip)\n\n if (result.exitCode !== 0) {\n // Show any error output\n if (result.stderr) {\n logger.error(result.stderr);\n }\n process.exit(result.exitCode);\n }\n\n return parsed;\n } catch (err) {\n registrySpinner.fail();\n logger.error(\"Failed to add components\");\n process.exit(1);\n }\n}\n\nexport const add = new Command()\n .name(\"add\")\n .description(\"Add components via shadcn@latest using registry URLs\")\n .argument(\"[components...]\", \"Component package names to add\")\n .option(\"-y, --yes\", \"skip confirmation prompt.\", false)\n .option(\"-o, --overwrite\", \"overwrite existing files.\", false)\n .option(\n \"-c, --cwd <cwd>\",\n \"the working directory. defaults to the current directory.\",\n process.cwd(),\n )\n .option(\"-a, --all\", \"add all available components\", false)\n .option(\"-p, --path <path>\", \"the path to add the component to.\")\n .option(\"-s, --silent\", \"mute output.\", false)\n .option(\n \"--src-dir\",\n \"use the src directory when creating a new project.\",\n false,\n )\n .option(\n \"--no-src-dir\",\n \"do not use the src directory when creating a new project.\",\n )\n // .option(\"--css-variables\", \"use css variables for theming.\", true)\n // .option(\"--no-css-variables\", \"do not use css variables for theming.\")\n .action(async function action(packages: string[], _opts, cmd) {\n const root = cmd?.parent;\n const verbose = Boolean(root?.opts?.().verbose);\n const rawArgv = process.argv.slice(2);\n const forwardedOptions = extractOptionsForShadcn(rawArgv, cmd);\n const opts =\n typeof cmd.optsWithGlobals === \"function\"\n ? cmd.optsWithGlobals()\n : (cmd.opts?.() ?? {});\n const cwd = opts.cwd || process.cwd();\n\n let componentsToAdd = packages || [];\n const wantsAll = Boolean(opts.all);\n const isSilent = opts.silent || false;\n const registryUrl = process.env.REGISTRY_URL || DEFAULT_REGISTRY_URL;\n\n // Handle --all flag: fetch all available components\n if (wantsAll && componentsToAdd.length === 0) {\n const fetchingSpinner = spinner(\"Fetching available components.\", {\n silent: isSilent,\n }).start();\n try {\n const allComponents = await fetchAvailableComponents(registryUrl);\n const uiComponents = allComponents.filter(\n (c) => !c.type || c.type === \"registry:ui\",\n );\n componentsToAdd = uiComponents.map((c) => c.name);\n fetchingSpinner.succeed();\n } catch (error) {\n fetchingSpinner.fail();\n logger.error(\"Failed to fetch available components from registry.\");\n process.exit(1);\n }\n }\n\n // Interactive mode: prompt user to select components\n if (componentsToAdd.length === 0) {\n const selected = await promptForComponents(registryUrl);\n if (!selected || selected.length === 0) {\n // User cancelled or no selection\n return;\n }\n componentsToAdd = selected;\n }\n\n // Get config for resolved paths (needed for reorganization)\n // In monorepos, we need to follow the alias chain to find the actual UI package config\n const config = await getConfig(cwd);\n\n // Try to get workspace config (follows aliases to find package-specific configs)\n let uiDir = config?.resolvedPaths?.ui || \"\";\n let uiConfig = config;\n\n if (config) {\n const workspaceConfig = await getWorkspaceConfig(config);\n if (workspaceConfig?.ui) {\n // Use the UI package's own config (e.g., packages/ui/components.json)\n uiConfig = workspaceConfig.ui;\n uiDir = uiConfig.resolvedPaths?.ui || uiDir;\n }\n }\n\n if (verbose) {\n logger.info(`[bejamas-ui] cwd: ${cwd}`);\n logger.info(`[bejamas-ui] uiDir: ${uiDir}`);\n logger.info(\n `[bejamas-ui] aliases.ui: ${uiConfig?.aliases?.ui || \"not set\"}`,\n );\n }\n\n // Process components ONE AT A TIME to avoid index.ts conflicts\n // When shadcn runs with multiple components, files with same name overwrite each other\n const totalComponents = componentsToAdd.length;\n\n for (let i = 0; i < componentsToAdd.length; i++) {\n const component = componentsToAdd[i];\n\n // Show component header when adding multiple\n if (totalComponents > 1 && !isSilent) {\n logger.break();\n logger.info(\n highlighter.info(`[${i + 1}/${totalComponents}]`) +\n ` Adding ${highlighter.success(component)}...`,\n );\n }\n\n // Build subfolder map for this single component\n const subfolderMapResult = await buildSubfolderMap(\n [component],\n registryUrl,\n );\n\n // Run shadcn for just this component\n const parsed = await addComponents(\n [component],\n forwardedOptions,\n verbose,\n isSilent,\n subfolderMapResult,\n );\n\n // Immediately reorganize this component's files before the next one\n let skippedCount = 0;\n if (uiDir) {\n const reorgResult = await reorganizeComponents(\n [component],\n uiDir,\n registryUrl,\n verbose,\n );\n skippedCount = reorgResult.skippedFiles.length;\n }\n\n // Display accurate results (accounting for files we skipped after shadcn \"created\" them)\n if (!isSilent) {\n const relativeUiDir = uiDir ? path.relative(cwd, uiDir) : \"\";\n\n // Files that were actually created (shadcn created minus our skipped)\n const actuallyCreated = Math.max(\n 0,\n parsed.created.length - skippedCount,\n );\n\n if (actuallyCreated > 0) {\n const createdPaths = rewritePaths(\n parsed.created.slice(0, actuallyCreated),\n subfolderMapResult,\n );\n logger.success(\n `Created ${createdPaths.length} file${createdPaths.length > 1 ? \"s\" : \"\"}:`,\n );\n for (const file of createdPaths) {\n logger.log(` ${highlighter.info(\"-\")} ${file}`);\n }\n }\n\n // Updated files (globals.css etc)\n if (parsed.updated.length > 0) {\n const uniqueUpdated = Array.from(new Set(parsed.updated));\n const updatedPaths = rewritePaths(uniqueUpdated, subfolderMapResult);\n logger.info(\n `Updated ${updatedPaths.length} file${updatedPaths.length > 1 ? \"s\" : \"\"}:`,\n );\n for (const file of updatedPaths) {\n logger.log(` ${highlighter.info(\"-\")} ${file}`);\n }\n }\n\n // Files skipped because they already exist in subfolder\n if (skippedCount > 0) {\n logger.info(\n `Skipped ${skippedCount} file${skippedCount > 1 ? \"s\" : \"\"}: (already exists)`,\n );\n }\n\n // Files shadcn skipped (different from our reorganization skip)\n if (parsed.skipped.length > 0) {\n const skippedPaths = rewritePaths(parsed.skipped, subfolderMapResult);\n logger.info(\n `Skipped ${skippedPaths.length} file${skippedPaths.length > 1 ? \"s\" : \"\"}: (use --overwrite)`,\n );\n for (const file of skippedPaths) {\n logger.log(` ${highlighter.info(\"-\")} ${file}`);\n }\n }\n\n // Nothing happened\n if (\n actuallyCreated === 0 &&\n parsed.updated.length === 0 &&\n skippedCount === 0 &&\n parsed.skipped.length === 0\n ) {\n logger.info(\"Already up to date.\");\n }\n }\n }\n\n // Fix aliases inside Astro files until upstream adds .astro support.\n await fixAstroImports(cwd, verbose);\n });\n","#!/usr/bin/env node\n\nimport { Command } from \"commander\";\nimport { createRequire } from \"module\";\nimport { init } from \"@/src/commands/init\";\nimport { docs } from \"@/src/commands/docs\";\nimport { docsCheck } from \"@/src/commands/docs-check\";\nimport { add } from \"@/src/commands/add\";\n\nconst require = createRequire(import.meta.url);\nconst pkg = require(\"../package.json\");\n\nconst program = new Command()\n .name(\"bejamas\")\n .description(\"bejamas/ui cli\")\n .configureHelp({\n helpWidth: Math.min(100, process.stdout.columns || 100),\n })\n .version(pkg.version, \"-v, --version\", \"output the version number\");\n\nprogram.addCommand(init);\nprogram.addCommand(add);\nprogram.addCommand(docs);\nprogram.addCommand(docsCheck);\n\nprogram.parse(process.argv);\n\nexport default program;\n"],"mappings":"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"}
@@ -13,7 +13,7 @@ import { readdir } from "fs/promises";
13
13
  import { Project, SyntaxKind } from "ts-morph";
14
14
 
15
15
  //#region src/registry/constants.ts
16
- const REGISTRY_URL = process.env.REGISTRY_URL ?? "http://localhost:4321/r";
16
+ const REGISTRY_URL = process.env.REGISTRY_URL ?? "https://ui.bejamas.com/r";
17
17
  const BASE_COLORS = [
18
18
  {
19
19
  name: "neutral",
@@ -514,4 +514,4 @@ function createSourceFileFromFrontmatter(frontmatterCode) {
514
514
 
515
515
  //#endregion
516
516
  export { BASE_COLORS as S, getWorkspaceConfig as _, extractComponentTagsFromMDX as a, logger as b, extractPropsFromDeclaredProps as c, parseJsDocMetadata as d, resolveOutDir as f, getConfig as g, toIdentifier as h, discoverExamples as i, normalizeBlockMDX as l, slugify as m, createSourceFileFromFrontmatter as n, extractFrontmatter as o, resolveUiRoot as p, detectHasImportTopLevel as r, extractPropsFromAstroProps as s, RESERVED_COMPONENTS as t, normalizeUsageMDX as u, getProjectInfo as v, highlighter as x, spinner as y };
517
- //# sourceMappingURL=utils-BXyPCddm.js.map
517
+ //# sourceMappingURL=utils-YFyZFTwZ.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils-YFyZFTwZ.js","names":["BUILTIN_REGISTRIES: z.infer<typeof registryConfigSchema>","fs","type: ProjectInfo","fs","resolvedAliases: any","key","RESERVED_COMPONENTS: Set<string>","meta: Record<string, any>","usageLines: string[]","examplesLines: string[]","primaryExampleLines: string[]","descriptionBodyLines: string[]","current: any","nameNode: any","defaultValue: string | undefined","match: RegExpExecArray | null","found: string[]","pathPosix"],"sources":["../src/registry/constants.ts","../src/utils/highlighter.ts","../src/utils/logger.ts","../src/utils/spinner.ts","../src/utils/get-package-info.ts","../src/utils/get-project-info.ts","../src/utils/resolve-import.ts","../src/utils/get-config.ts","../src/docs/generate-mdx/utils.ts"],"sourcesContent":["import { registryConfigSchema } from \"shadcn/schema\";\nimport { z } from \"zod\";\n\nexport const REGISTRY_URL =\n process.env.REGISTRY_URL ?? \"https://ui.bejamas.com/r\";\n\nexport const FALLBACK_STYLE = \"new-york-v4\";\n\nexport const BASE_COLORS = [\n {\n name: \"neutral\",\n label: \"Neutral\",\n },\n {\n name: \"gray\",\n label: \"Gray\",\n },\n {\n name: \"zinc\",\n label: \"Zinc\",\n },\n {\n name: \"stone\",\n label: \"Stone\",\n },\n {\n name: \"slate\",\n label: \"Slate\",\n },\n] as const;\n\n// Built-in registries that are always available and cannot be overridden\nexport const BUILTIN_REGISTRIES: z.infer<typeof registryConfigSchema> = {\n \"@bejamas\": `${REGISTRY_URL}/{name}.json`,\n};\n\nexport const BUILTIN_MODULES = new Set([\n [\n // Node.js built-in modules\n // From https://github.com/sindresorhus/builtin-modules.\n \"node:assert\",\n \"assert\",\n \"node:assert/strict\",\n \"assert/strict\",\n \"node:async_hooks\",\n \"async_hooks\",\n \"node:buffer\",\n \"buffer\",\n \"node:child_process\",\n \"child_process\",\n \"node:cluster\",\n \"cluster\",\n \"node:console\",\n \"console\",\n \"node:constants\",\n \"constants\",\n \"node:crypto\",\n \"crypto\",\n \"node:dgram\",\n \"dgram\",\n \"node:diagnostics_channel\",\n \"diagnostics_channel\",\n \"node:dns\",\n \"dns\",\n \"node:dns/promises\",\n \"dns/promises\",\n \"node:domain\",\n \"domain\",\n \"node:events\",\n \"events\",\n \"node:fs\",\n \"fs\",\n \"node:fs/promises\",\n \"fs/promises\",\n \"node:http\",\n \"http\",\n \"node:http2\",\n \"http2\",\n \"node:https\",\n \"https\",\n \"node:inspector\",\n \"inspector\",\n \"node:inspector/promises\",\n \"inspector/promises\",\n \"node:module\",\n \"module\",\n \"node:net\",\n \"net\",\n \"node:os\",\n \"os\",\n \"node:path\",\n \"path\",\n \"node:path/posix\",\n \"path/posix\",\n \"node:path/win32\",\n \"path/win32\",\n \"node:perf_hooks\",\n \"perf_hooks\",\n \"node:process\",\n \"process\",\n \"node:querystring\",\n \"querystring\",\n \"node:quic\",\n \"node:readline\",\n \"readline\",\n \"node:readline/promises\",\n \"readline/promises\",\n \"node:repl\",\n \"repl\",\n \"node:sea\",\n \"node:sqlite\",\n \"node:stream\",\n \"stream\",\n \"node:stream/consumers\",\n \"stream/consumers\",\n \"node:stream/promises\",\n \"stream/promises\",\n \"node:stream/web\",\n \"stream/web\",\n \"node:string_decoder\",\n \"string_decoder\",\n \"node:test\",\n \"node:test/reporters\",\n \"node:timers\",\n \"timers\",\n \"node:timers/promises\",\n \"timers/promises\",\n \"node:tls\",\n \"tls\",\n \"node:trace_events\",\n \"trace_events\",\n \"node:tty\",\n \"tty\",\n \"node:url\",\n \"url\",\n \"node:util\",\n \"util\",\n \"node:util/types\",\n \"util/types\",\n \"node:v8\",\n \"v8\",\n \"node:vm\",\n \"vm\",\n \"node:wasi\",\n \"wasi\",\n \"node:worker_threads\",\n \"worker_threads\",\n \"node:zlib\",\n \"zlib\",\n\n // Bun built-in modules.\n \"bun\",\n \"bun:test\",\n \"bun:sqlite\",\n \"bun:ffi\",\n \"bun:jsc\",\n \"bun:internal\",\n ],\n]);\n\nexport const DEPRECATED_COMPONENTS = [\n {\n name: \"toast\",\n deprecatedBy: \"sonner\",\n message:\n \"The toast component is deprecated. Use the sonner component instead.\",\n },\n {\n name: \"toaster\",\n deprecatedBy: \"sonner\",\n message:\n \"The toaster component is deprecated. Use the sonner component instead.\",\n },\n];\n","import { cyan, green, red, yellow } from \"kleur/colors\";\n\nexport const highlighter = {\n error: red,\n warn: yellow,\n info: cyan,\n success: green,\n};\n","import { highlighter } from \"@/src/utils/highlighter\";\n\nexport const logger = {\n error(...args: unknown[]) {\n console.log(highlighter.error(args.join(\" \")));\n },\n warn(...args: unknown[]) {\n console.log(highlighter.warn(args.join(\" \")));\n },\n info(...args: unknown[]) {\n console.log(highlighter.info(args.join(\" \")));\n },\n success(...args: unknown[]) {\n console.log(highlighter.success(args.join(\" \")));\n },\n log(...args: unknown[]) {\n console.log(args.join(\" \"));\n },\n break() {\n console.log(\"\");\n },\n};\n","import ora, { type Options } from \"ora\";\n\nexport function spinner(\n text: Options[\"text\"],\n options?: {\n silent?: boolean;\n },\n) {\n return ora({\n text,\n isSilent: options?.silent,\n });\n}\n","import path from \"path\";\nimport fs from \"fs-extra\";\nimport { type PackageJson } from \"type-fest\";\n\nexport function getPackageInfo(\n cwd: string = \"\",\n shouldThrow: boolean = true,\n): PackageJson | null {\n const packageJsonPath = path.join(cwd, \"package.json\");\n\n return fs.readJSONSync(packageJsonPath, {\n throws: shouldThrow,\n }) as PackageJson;\n}\n","import path from \"path\";\nimport { rawConfigSchema } from \"shadcn/schema\";\nimport { Config, getConfig, resolveConfigPaths } from \"@/src/utils/get-config\";\nimport { getPackageInfo } from \"@/src/utils/get-package-info\";\nimport fg from \"fast-glob\";\nimport fs from \"fs-extra\";\nimport { loadConfig } from \"tsconfig-paths\";\nimport { z } from \"zod\";\n\nexport type TailwindVersion = \"v3\" | \"v4\" | null;\n\nexport type ProjectInfo = {\n isAstro: boolean;\n tailwindConfigFile: string | null;\n tailwindCssFile: string | null;\n tailwindVersion: TailwindVersion;\n aliasPrefix: string | null;\n};\n\nconst PROJECT_SHARED_IGNORE = [\n \"**/node_modules/**\",\n \".astro\",\n \"public\",\n \"dist\",\n \"build\",\n];\n\nconst TS_CONFIG_SCHEMA = z.object({\n compilerOptions: z.object({\n paths: z.record(z.string().or(z.array(z.string()))),\n }),\n});\n\nexport async function getProjectInfo(cwd: string): Promise<ProjectInfo | null> {\n const [\n configFiles,\n tailwindConfigFile,\n tailwindCssFile,\n tailwindVersion,\n aliasPrefix,\n packageJson,\n ] = await Promise.all([\n fg.glob(\n \"**/{next,vite,astro,app}.config.*|gatsby-config.*|composer.json|react-router.config.*\",\n {\n cwd,\n deep: 3,\n ignore: PROJECT_SHARED_IGNORE,\n },\n ),\n getTailwindConfigFile(cwd),\n getTailwindCssFile(cwd),\n getTailwindVersion(cwd),\n getTsConfigAliasPrefix(cwd),\n getPackageInfo(cwd, false),\n ]);\n\n const type: ProjectInfo = {\n isAstro: false,\n tailwindConfigFile,\n tailwindCssFile,\n tailwindVersion,\n aliasPrefix,\n };\n\n // Astro.\n if (configFiles.find((file) => file.startsWith(\"astro.config.\"))?.length) {\n type.isAstro = true;\n return type;\n }\n\n return type;\n}\n\nexport async function getTailwindVersion(\n cwd: string,\n): Promise<ProjectInfo[\"tailwindVersion\"]> {\n const [packageInfo, config] = await Promise.all([\n getPackageInfo(cwd, false),\n getConfig(cwd),\n ]);\n\n // If the config file is empty, we can assume that it's a v4 project.\n if (config?.tailwind?.config === \"\") {\n return \"v4\";\n }\n\n if (\n !packageInfo?.dependencies?.tailwindcss &&\n !packageInfo?.devDependencies?.tailwindcss\n ) {\n return null;\n }\n\n if (\n /^(?:\\^|~)?3(?:\\.\\d+)*(?:-.*)?$/.test(\n packageInfo?.dependencies?.tailwindcss ||\n packageInfo?.devDependencies?.tailwindcss ||\n \"\",\n )\n ) {\n return \"v3\";\n }\n\n return \"v4\";\n}\n\nexport async function getTailwindCssFile(cwd: string) {\n const [files, tailwindVersion] = await Promise.all([\n fg.glob([\"**/*.css\", \"**/*.scss\"], {\n cwd,\n deep: 5,\n ignore: PROJECT_SHARED_IGNORE,\n }),\n getTailwindVersion(cwd),\n ]);\n\n if (!files.length) {\n return null;\n }\n\n const needle =\n tailwindVersion === \"v4\" ? `@import \"tailwindcss\"` : \"@tailwind base\";\n for (const file of files) {\n const contents = await fs.readFile(path.resolve(cwd, file), \"utf8\");\n if (\n contents.includes(`@import \"tailwindcss\"`) ||\n contents.includes(`@import 'tailwindcss'`) ||\n contents.includes(`@tailwind base`)\n ) {\n return file;\n }\n }\n\n return null;\n}\n\nexport async function getTailwindConfigFile(cwd: string) {\n const files = await fg.glob(\"tailwind.config.*\", {\n cwd,\n deep: 3,\n ignore: PROJECT_SHARED_IGNORE,\n });\n\n if (!files.length) {\n return null;\n }\n\n return files[0];\n}\n\nexport async function getTsConfigAliasPrefix(cwd: string) {\n const tsConfig = await loadConfig(cwd);\n\n if (\n tsConfig?.resultType === \"failed\" ||\n !Object.entries(tsConfig?.paths).length\n ) {\n return null;\n }\n\n // This assume that the first alias is the prefix.\n for (const [alias, paths] of Object.entries(tsConfig.paths)) {\n if (\n paths.includes(\"./*\") ||\n paths.includes(\"./src/*\") ||\n paths.includes(\"./app/*\") ||\n paths.includes(\"./resources/js/*\") // Laravel.\n ) {\n return alias.replace(/\\/\\*$/, \"\") ?? null;\n }\n }\n\n // Use the first alias as the prefix.\n return Object.keys(tsConfig?.paths)?.[0].replace(/\\/\\*$/, \"\") ?? null;\n}\n\nexport async function isTypeScriptProject(cwd: string) {\n const files = await fg.glob(\"tsconfig.*\", {\n cwd,\n deep: 1,\n ignore: PROJECT_SHARED_IGNORE,\n });\n\n return files.length > 0;\n}\n\nexport async function getTsConfig(cwd: string) {\n for (const fallback of [\n \"tsconfig.json\",\n \"tsconfig.web.json\",\n \"tsconfig.app.json\",\n ]) {\n const filePath = path.resolve(cwd, fallback);\n if (!(await fs.pathExists(filePath))) {\n continue;\n }\n\n // We can't use fs.readJSON because it doesn't support comments.\n const contents = await fs.readFile(filePath, \"utf8\");\n const cleanedContents = contents.replace(/\\/\\*\\s*\\*\\//g, \"\");\n const result = TS_CONFIG_SCHEMA.safeParse(JSON.parse(cleanedContents));\n\n if (result.error) {\n continue;\n }\n\n return result.data;\n }\n\n return null;\n}\n\nexport async function getProjectConfig(\n cwd: string,\n defaultProjectInfo: ProjectInfo | null = null,\n): Promise<Config | null> {\n // Check for existing component config.\n const [existingConfig, projectInfo] = await Promise.all([\n getConfig(cwd),\n !defaultProjectInfo\n ? getProjectInfo(cwd)\n : Promise.resolve(defaultProjectInfo),\n ]);\n\n if (existingConfig) {\n return existingConfig;\n }\n\n if (\n !projectInfo ||\n !projectInfo.tailwindCssFile ||\n (projectInfo.tailwindVersion === \"v3\" && !projectInfo.tailwindConfigFile)\n ) {\n return null;\n }\n\n const config: z.infer<typeof rawConfigSchema> = {\n $schema: \"https://ui.shadcn.com/schema.json\",\n style: \"new-york\",\n tailwind: {\n config: projectInfo.tailwindConfigFile ?? \"\",\n baseColor: \"zinc\",\n css: projectInfo.tailwindCssFile,\n cssVariables: true,\n prefix: \"\",\n },\n iconLibrary: \"lucide\",\n aliases: {\n components: `${projectInfo.aliasPrefix}/components`,\n ui: `${projectInfo.aliasPrefix}/components/ui`,\n lib: `${projectInfo.aliasPrefix}/lib`,\n utils: `${projectInfo.aliasPrefix}/lib/utils`,\n },\n };\n\n return await resolveConfigPaths(cwd, config);\n}\n\nexport async function getProjectTailwindVersionFromConfig(config: {\n resolvedPaths: Pick<Config[\"resolvedPaths\"], \"cwd\">;\n}): Promise<TailwindVersion> {\n if (!config.resolvedPaths?.cwd) {\n return \"v3\";\n }\n\n const projectInfo = await getProjectInfo(config.resolvedPaths.cwd);\n\n if (!projectInfo?.tailwindVersion) {\n return null;\n }\n\n return projectInfo.tailwindVersion;\n}\n","import {\n createMatchPath,\n type ConfigLoaderSuccessResult,\n} from \"tsconfig-paths\";\n\nexport async function resolveImport(\n importPath: string,\n config: Pick<ConfigLoaderSuccessResult, \"absoluteBaseUrl\" | \"paths\">,\n) {\n return createMatchPath(config.absoluteBaseUrl, config.paths)(\n importPath,\n undefined,\n () => true,\n [\".ts\", \".tsx\", \".jsx\", \".js\", \".css\"],\n );\n}\n","import path from \"path\";\nimport { BUILTIN_REGISTRIES } from \"@/src/registry/constants\";\nimport {\n configSchema,\n rawConfigSchema,\n workspaceConfigSchema,\n} from \"shadcn/schema\";\nimport { getProjectInfo } from \"@/src/utils/get-project-info\";\nimport { highlighter } from \"@/src/utils/highlighter\";\nimport { resolveImport } from \"@/src/utils/resolve-import\";\nimport { cosmiconfig } from \"cosmiconfig\";\nimport fg from \"fast-glob\";\nimport { loadConfig } from \"tsconfig-paths\";\nimport { z } from \"zod\";\n\nexport const DEFAULT_STYLE = \"default\";\nexport const DEFAULT_COMPONENTS = \"@/components\";\nexport const DEFAULT_UTILS = \"@/lib/utils\";\nexport const DEFAULT_TAILWIND_CSS = \"app/globals.css\";\nexport const DEFAULT_TAILWIND_CONFIG = \"tailwind.config.js\";\nexport const DEFAULT_TAILWIND_BASE_COLOR = \"slate\";\n\n// TODO: Figure out if we want to support all cosmiconfig formats.\n// A simple components.json file would be nice.\nexport const explorer = cosmiconfig(\"components\", {\n searchPlaces: [\"components.json\"],\n});\n\nexport type Config = z.infer<typeof configSchema>;\n\nexport async function getConfig(cwd: string) {\n const config = await getRawConfig(cwd);\n\n if (!config) {\n return null;\n }\n\n // Set default icon library if not provided.\n if (!config.iconLibrary) {\n config.iconLibrary = config.style === \"new-york\" ? \"radix\" : \"lucide\";\n }\n\n return await resolveConfigPaths(cwd, config);\n}\n\nexport async function resolveConfigPaths(\n cwd: string,\n config: z.infer<typeof rawConfigSchema>,\n) {\n // Merge built-in registries with user registries\n config.registries = {\n ...BUILTIN_REGISTRIES,\n ...(config.registries || {}),\n };\n\n // Read tsconfig.json.\n const tsConfig = await loadConfig(cwd);\n\n if (tsConfig.resultType === \"failed\") {\n throw new Error(\n `Failed to load ${config.tsx ? \"tsconfig\" : \"jsconfig\"}.json. ${\n tsConfig.message ?? \"\"\n }`.trim(),\n );\n }\n\n return configSchema.parse({\n ...config,\n resolvedPaths: {\n cwd,\n tailwindConfig: config.tailwind.config\n ? path.resolve(cwd, config.tailwind.config)\n : \"\",\n tailwindCss: path.resolve(cwd, config.tailwind.css),\n utils: await resolveImport(config.aliases[\"utils\"], tsConfig),\n components: await resolveImport(config.aliases[\"components\"], tsConfig),\n ui: config.aliases[\"ui\"]\n ? await resolveImport(config.aliases[\"ui\"], tsConfig)\n : path.resolve(\n (await resolveImport(config.aliases[\"components\"], tsConfig)) ??\n cwd,\n \"ui\",\n ),\n // TODO: Make this configurable.\n // For now, we assume the lib and hooks directories are one level up from the components directory.\n lib: config.aliases[\"lib\"]\n ? await resolveImport(config.aliases[\"lib\"], tsConfig)\n : path.resolve(\n (await resolveImport(config.aliases[\"utils\"], tsConfig)) ?? cwd,\n \"..\",\n ),\n hooks: config.aliases[\"hooks\"]\n ? await resolveImport(config.aliases[\"hooks\"], tsConfig)\n : path.resolve(\n (await resolveImport(config.aliases[\"components\"], tsConfig)) ??\n cwd,\n \"..\",\n \"hooks\",\n ),\n },\n });\n}\n\nexport async function getRawConfig(\n cwd: string,\n): Promise<z.infer<typeof rawConfigSchema> | null> {\n try {\n const configResult = await explorer.search(cwd);\n\n if (!configResult) {\n return null;\n }\n\n const config = rawConfigSchema.parse(configResult.config);\n\n // Check if user is trying to override built-in registries\n if (config.registries) {\n for (const registryName of Object.keys(config.registries)) {\n if (registryName in BUILTIN_REGISTRIES) {\n throw new Error(\n `\"${registryName}\" is a built-in registry and cannot be overridden.`,\n );\n }\n }\n }\n\n return config;\n } catch (error) {\n const componentPath = `${cwd}/components.json`;\n if (error instanceof Error && error.message.includes(\"reserved registry\")) {\n throw error;\n }\n throw new Error(\n `Invalid configuration found in ${highlighter.info(componentPath)}.`,\n );\n }\n}\n\n// Note: we can check for -workspace.yaml or \"workspace\" in package.json.\n// Since cwd is not necessarily the root of the project.\n// We'll instead check if ui aliases resolve to a different root.\nexport async function getWorkspaceConfig(config: Config) {\n let resolvedAliases: any = {};\n\n for (const key of Object.keys(config.aliases)) {\n if (!isAliasKey(key, config)) {\n continue;\n }\n\n const resolvedPath = config.resolvedPaths[key];\n const packageRoot = await findPackageRoot(\n config.resolvedPaths.cwd,\n resolvedPath,\n );\n\n if (!packageRoot) {\n resolvedAliases[key] = config;\n continue;\n }\n\n resolvedAliases[key] = await getConfig(packageRoot);\n }\n\n const result = workspaceConfigSchema.safeParse(resolvedAliases);\n if (!result.success) {\n return null;\n }\n\n return result.data;\n}\n\nexport async function findPackageRoot(cwd: string, resolvedPath: string) {\n const commonRoot = findCommonRoot(cwd, resolvedPath);\n const relativePath = path.relative(commonRoot, resolvedPath);\n\n const packageRoots = await fg.glob(\"**/package.json\", {\n cwd: commonRoot,\n deep: 3,\n ignore: [\"**/node_modules/**\", \"**/dist/**\", \"**/build/**\", \"**/public/**\"],\n });\n\n const matchingPackageRoot = packageRoots\n .map((pkgPath) => path.dirname(pkgPath))\n .find((pkgDir) => relativePath.startsWith(pkgDir));\n\n return matchingPackageRoot\n ? path.join(commonRoot, matchingPackageRoot)\n : null;\n}\n\nfunction isAliasKey(\n key: string,\n config: Config,\n): key is keyof Config[\"aliases\"] {\n return Object.keys(config.resolvedPaths)\n .filter((key) => key !== \"utils\")\n .includes(key);\n}\n\nexport function findCommonRoot(cwd: string, resolvedPath: string) {\n const parts1 = cwd.split(path.sep);\n const parts2 = resolvedPath.split(path.sep);\n const commonParts = [];\n\n for (let i = 0; i < Math.min(parts1.length, parts2.length); i++) {\n if (parts1[i] !== parts2[i]) {\n break;\n }\n commonParts.push(parts1[i]);\n }\n\n return commonParts.join(path.sep);\n}\n\n// TODO: Cache this call.\nexport async function getTargetStyleFromConfig(cwd: string, fallback: string) {\n const projectInfo = await getProjectInfo(cwd);\n return projectInfo?.tailwindVersion === \"v4\" ? \"new-york-v4\" : fallback;\n}\n\ntype DeepPartial<T> = {\n [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];\n};\n\n/**\n * Creates a config object with sensible defaults.\n * Useful for universal registry items that bypass framework detection.\n *\n * @param partial - Partial config values to override defaults\n * @returns A complete Config object\n */\nexport function createConfig(partial?: DeepPartial<Config>): Config {\n const defaultConfig: Config = {\n resolvedPaths: {\n cwd: process.cwd(),\n tailwindConfig: \"\",\n tailwindCss: \"\",\n utils: \"\",\n components: \"\",\n ui: \"\",\n lib: \"\",\n hooks: \"\",\n },\n style: \"\",\n tailwind: {\n config: \"\",\n css: \"\",\n baseColor: \"\",\n cssVariables: false,\n },\n rsc: false,\n tsx: true,\n aliases: {\n components: \"\",\n utils: \"\",\n },\n registries: {\n ...BUILTIN_REGISTRIES,\n },\n };\n\n // Deep merge the partial config with defaults\n if (partial) {\n return {\n ...defaultConfig,\n ...partial,\n resolvedPaths: {\n ...defaultConfig.resolvedPaths,\n ...(partial.resolvedPaths || {}),\n },\n tailwind: {\n ...defaultConfig.tailwind,\n ...(partial.tailwind || {}),\n },\n aliases: {\n ...defaultConfig.aliases,\n ...(partial.aliases || {}),\n },\n registries: {\n ...defaultConfig.registries,\n ...(partial.registries || {}),\n },\n };\n }\n\n return defaultConfig;\n}\n","import { existsSync, readFileSync } from \"fs\";\nimport { readdir } from \"fs/promises\";\nimport path, { dirname, extname, join, posix as pathPosix } from \"path\";\nimport { createRequire } from \"module\";\nimport { Project, SyntaxKind, SourceFile } from \"ts-morph\";\n\nexport const RESERVED_COMPONENTS: Set<string> = new Set([\n \"Fragment\",\n \"CodePackageManagers\",\n \"DocsTabs\",\n \"DocsTabItem\",\n \"DocsCodePackageManagers\",\n \"Tabs\",\n \"TabItem\",\n]);\n\nexport function slugify(input: string): string {\n return input\n .replace(/\\.(astro|md|mdx|tsx|ts|jsx|js)$/i, \"\")\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .replace(/\\s+/g, \"-\")\n .replace(/_+/g, \"-\")\n .toLowerCase();\n}\n\nexport function extractFrontmatter(source: string): string {\n const match = source.match(/^---\\n([\\s\\S]*?)\\n---/);\n return (match && match[1]) || \"\";\n}\n\nexport function toIdentifier(name: string): string {\n const base = name\n .replace(/\\.[^.]+$/, \"\")\n .replace(/[^a-zA-Z0-9]+/g, \" \")\n .trim()\n .replace(/\\b\\w/g, (c) => c.toUpperCase())\n .replace(/\\s+/g, \"\");\n return /^[A-Za-z_]/.test(base) ? base : `Ex${base}`;\n}\n\nexport function parseJsDocMetadata(\n frontmatterCode: string,\n): Record<string, any> {\n const jsDocMatch = frontmatterCode.match(/\\/\\*\\*([\\s\\S]*?)\\*\\//);\n if (!jsDocMatch) return {};\n const content = jsDocMatch[1];\n const lines = content.split(\"\\n\").map((l) => l.replace(/^\\s*\\*\\s?/, \"\"));\n const meta: Record<string, any> = {};\n let inUsage = false;\n let inExamples = false;\n let inPrimaryExample = false;\n let captureDescriptionBody = false;\n const usageLines: string[] = [];\n const examplesLines: string[] = [];\n const primaryExampleLines: string[] = [];\n const descriptionBodyLines: string[] = [];\n for (const rawLine of lines) {\n const line = rawLine;\n if (inUsage) {\n if (line.trim().startsWith(\"@\")) {\n inUsage = false;\n } else {\n usageLines.push(line);\n continue;\n }\n }\n if (inPrimaryExample) {\n if (line.trim().startsWith(\"@\")) {\n inPrimaryExample = false;\n } else {\n primaryExampleLines.push(line);\n continue;\n }\n }\n if (inExamples) {\n if (line.trim().startsWith(\"@\")) {\n inExamples = false;\n } else {\n examplesLines.push(line);\n continue;\n }\n }\n if (captureDescriptionBody) {\n if (line.trim().startsWith(\"@\")) {\n captureDescriptionBody = false;\n } else {\n descriptionBodyLines.push(line);\n continue;\n }\n }\n if (line.trim().startsWith(\"@component\"))\n meta.name = line.replace(\"@component\", \"\").trim();\n else if (line.trim().startsWith(\"@title\"))\n meta.title = line.replace(\"@title\", \"\").trim();\n else if (line.trim().startsWith(\"@description\")) {\n meta.description = line.replace(\"@description\", \"\").trim();\n captureDescriptionBody = true;\n continue;\n } else if (line.trim().startsWith(\"@figmaUrl\"))\n meta.figmaUrl = line.replace(\"@figmaUrl\", \"\").trim();\n // Backward compatibility: support @figma but map to figmaUrl\n else if (line.trim().startsWith(\"@figma\"))\n meta.figmaUrl = line.replace(\"@figma\", \"\").trim();\n else if (line.trim().startsWith(\"@usage\")) {\n inUsage = true;\n continue;\n } else if (line.trim().startsWith(\"@examples\")) {\n inExamples = true;\n continue;\n } else if (line.trim().startsWith(\"@preview\")) {\n inPrimaryExample = true;\n continue;\n } else if (line.trim().startsWith(\"@example\")) {\n // backward compatibility with older docs\n inPrimaryExample = true;\n continue;\n }\n }\n if (usageLines.length) meta.usageMDX = usageLines.join(\"\\n\").trim();\n if (examplesLines.length) meta.examplesMDX = examplesLines.join(\"\\n\").trim();\n if (primaryExampleLines.length)\n meta.primaryExampleMDX = primaryExampleLines.join(\"\\n\").trim();\n if (descriptionBodyLines.length)\n meta.descriptionBodyMDX = descriptionBodyLines.join(\"\\n\").trim();\n return meta;\n}\n\nexport function extractPropsFromAstroProps(sourceFile: SourceFile): Array<{\n name?: string;\n isRest?: boolean;\n hasDefault?: boolean;\n defaultValue?: string;\n alias?: string;\n}> {\n // Helper: unwrap expressions like `(Astro.props as Props)`, `Astro.props as Props`,\n // `<Props>Astro.props`, `(Astro.props)!`, and parenthesized variants until we reach\n // the underlying PropertyAccessExpression.\n function unwrapAstroProps(node: any): any | null {\n let current: any = node;\n // Unwrap layers that can wrap the property access\n // AsExpression, TypeAssertion, SatisfiesExpression, NonNullExpression, ParenthesizedExpression\n // Keep drilling down via getExpression()\n // Guard against cycles by limiting iterations\n for (let i = 0; i < 10; i += 1) {\n const kind = current.getKind();\n if (kind === SyntaxKind.PropertyAccessExpression) {\n const expr = current.getExpression();\n if (\n expr &&\n expr.getText() === \"Astro\" &&\n current.getName() === \"props\"\n ) {\n return current;\n }\n return null;\n }\n if (\n kind === SyntaxKind.AsExpression ||\n kind === SyntaxKind.TypeAssertion ||\n // @ts-ignore - SatisfiesExpression may not exist in older TS versions\n kind === (SyntaxKind as any).SatisfiesExpression ||\n kind === SyntaxKind.NonNullExpression ||\n kind === SyntaxKind.ParenthesizedExpression\n ) {\n const next = current.getExpression && current.getExpression();\n if (!next) return null;\n current = next;\n continue;\n }\n return null;\n }\n return null;\n }\n\n const declarations = sourceFile.getDescendantsOfKind(\n SyntaxKind.VariableDeclaration,\n );\n const target = declarations.find((decl) => {\n const init = decl.getInitializer();\n if (!init) return false;\n return !!unwrapAstroProps(init);\n });\n if (!target) return [];\n const nameNode: any = target.getNameNode();\n if (!nameNode || nameNode.getKind() !== SyntaxKind.ObjectBindingPattern)\n return [];\n const obj = nameNode.asKindOrThrow(SyntaxKind.ObjectBindingPattern);\n return obj.getElements().map((el: any) => {\n const isRest = !!el.getDotDotDotToken();\n if (isRest) return { isRest: true, hasDefault: false, alias: el.getName() };\n const propertyNameNode = el.getPropertyNameNode();\n const name = el.getName();\n const propName = propertyNameNode ? propertyNameNode.getText() : name;\n const initializer = el.getInitializer();\n let defaultValue: string | undefined;\n if (initializer) defaultValue = initializer.getText();\n return { name: propName, hasDefault: initializer != null, defaultValue };\n });\n}\n\nexport function extractPropsFromDeclaredProps(sourceFile: SourceFile): Array<{\n name: string;\n type: string;\n optional: boolean;\n}> {\n function normalizeTypeText(text: string | undefined): string {\n if (!text) return \"\";\n return text.replace(/\\s+/g, \" \").replace(/;\\s*$/, \"\").trim();\n }\n // Prefer interface Props\n const iface = sourceFile.getInterface(\"Props\");\n if (iface) {\n const properties = iface.getProperties();\n return properties.map((prop) => {\n const name = prop.getName();\n const typeNode = prop.getTypeNode();\n const rawType = typeNode ? typeNode.getText() : prop.getType().getText();\n const typeText = normalizeTypeText(rawType);\n const optional = prop.hasQuestionToken();\n return { name, type: typeText, optional };\n });\n }\n\n // Fallback: type Props = { ... }\n const typeAlias = sourceFile.getTypeAlias(\"Props\");\n if (typeAlias) {\n const typeNode = typeAlias.getTypeNode();\n if (typeNode && typeNode.getKind() === SyntaxKind.TypeLiteral) {\n const literal = typeNode.asKindOrThrow(SyntaxKind.TypeLiteral);\n const properties = literal.getProperties();\n return properties.map((prop) => {\n const name = prop.getName();\n const tn = prop.getTypeNode();\n const rawType = tn ? tn.getText() : prop.getType().getText();\n const typeText = normalizeTypeText(rawType);\n const optional = prop.hasQuestionToken();\n return { name, type: typeText, optional };\n });\n }\n }\n\n return [];\n}\n\nexport function resolveUiRoot(cwd: string): string {\n const require = createRequire(import.meta.url);\n\n const envRoot = process.env.BEJAMAS_UI_ROOT;\n if (envRoot && existsSync(path.join(envRoot, \"package.json\"))) {\n return envRoot;\n }\n\n try {\n const pkgPath = require.resolve(\"@bejamas/ui/package.json\", {\n paths: [cwd],\n });\n return path.dirname(pkgPath);\n } catch {}\n\n let current = cwd;\n for (let i = 0; i < 6; i += 1) {\n const candidate = path.join(current, \"packages\", \"ui\", \"package.json\");\n if (existsSync(candidate)) return path.dirname(candidate);\n const parent = path.dirname(current);\n if (parent === current) break;\n current = parent;\n }\n\n try {\n const anyEntry = require.resolve(\"@bejamas/ui/*\", { paths: [cwd] });\n return path.resolve(anyEntry, \"..\", \"..\");\n } catch {}\n\n throw new Error(\"Unable to locate @bejamas/ui in the workspace\");\n}\n\nexport function resolveOutDir(cwd: string): string {\n const envOut = process.env.BEJAMAS_DOCS_OUT_DIR;\n if (envOut && envOut.length) {\n return path.isAbsolute(envOut) ? envOut : path.resolve(cwd, envOut);\n }\n return path.resolve(cwd, \"../../apps/web/src/content/docs/components\");\n}\n\nexport function detectHasImportTopLevel(\n block: string,\n pascalName: string,\n): boolean {\n if (!block) return false;\n let inFence = false;\n const importLineRegex = new RegExp(\n `^\\\\s*import\\\\s+.*\\\\bfrom\\\\s+['\"][^'\"]+\\\\b${pascalName}\\\\.astro['\"]`,\n );\n for (const line of block.split(\"\\n\")) {\n const trimmed = line.trim();\n if (trimmed.startsWith(\"```\")) {\n inFence = !inFence;\n continue;\n }\n if (!inFence && importLineRegex.test(line)) return true;\n }\n return false;\n}\n\nexport function hasImportOfTopLevel(\n block: string,\n componentName: string,\n): boolean {\n if (!block) return false;\n let inFence = false;\n const importRegex = new RegExp(\n `^\\\\s*import\\\\s+[^;]*\\\\b${componentName}\\\\b[^;]*from\\\\s+['\"][^'\"]*(?:/|^)${componentName}\\\\.astro['\"]`,\n );\n const lucideIconRegex = /Icon$/.test(componentName)\n ? new RegExp(\n `^\\\\s*import\\\\s+\\\\{[^}]*\\\\b${componentName}\\\\b[^}]*\\\\}\\\\s+from\\\\s+['\"]@lucide/astro['\"]`,\n )\n : null;\n for (const line of block.split(\"\\n\")) {\n const trimmed = line.trim();\n if (trimmed.startsWith(\"```\")) {\n inFence = !inFence;\n continue;\n }\n if (!inFence && importRegex.test(line)) return true;\n if (!inFence && lucideIconRegex && lucideIconRegex.test(line)) return true;\n }\n return false;\n}\n\nexport function normalizeBlockMDX(block: string): string {\n if (!block) return \"\";\n return block.replace(\n /from\\s+['\"]@\\/ui\\/components\\//g,\n \"from '@bejamas/ui/components/\",\n );\n}\n\nexport function replaceDocsComponentTags(block: string): string {\n if (!block) return \"\";\n let inFence = false;\n const lines = block.split(\"\\n\");\n const out: string[] = [];\n for (const line of lines) {\n const trimmed = line.trim();\n if (trimmed.startsWith(\"```\")) {\n inFence = !inFence;\n out.push(line);\n continue;\n }\n if (inFence) {\n out.push(line);\n continue;\n }\n const replaced = line\n .replace(/<Tabs(\\b|\\s)/g, \"<DocsTabs$1\")\n .replace(/<\\/Tabs>/g, \"</DocsTabs>\")\n .replace(/<TabItem(\\b|\\s)/g, \"<DocsTabItem$1\")\n .replace(/<\\/TabItem>/g, \"</DocsTabItem>\");\n out.push(replaced);\n }\n return out.join(\"\\n\");\n}\n\nexport function normalizeUsageMDX(\n usageMDX: string,\n pascalName: string,\n): { text: string; hasImport: boolean } {\n const normalized = normalizeBlockMDX(usageMDX);\n const hasImport = detectHasImportTopLevel(normalized, pascalName);\n return { text: normalized.trim(), hasImport };\n}\n\nexport function extractComponentTagsFromMDX(block: string): string[] {\n if (!block) return [];\n let inFence = false;\n const found = new Set<string>();\n const tagRegex = /<([A-Z][A-Za-z0-9_]*)\\b/g;\n for (const line of block.split(\"\\n\")) {\n const trimmed = line.trim();\n if (trimmed.startsWith(\"```\")) {\n inFence = !inFence;\n continue;\n }\n if (inFence) continue;\n let match: RegExpExecArray | null;\n while ((match = tagRegex.exec(line)) !== null) {\n const name = match[1];\n found.add(name);\n }\n }\n return Array.from(found);\n}\n\nexport async function discoverExamples(\n componentFilePath: string,\n componentsDir: string,\n): Promise<string[]> {\n const fileBase = path.basename(\n componentFilePath,\n path.extname(componentFilePath),\n );\n const kebabBase = slugify(fileBase);\n const candidates = [\n join(dirname(componentFilePath), `${fileBase}.examples`),\n join(dirname(componentFilePath), `${kebabBase}.examples`),\n ];\n const found: string[] = [];\n for (const dir of candidates) {\n try {\n const items = await readdir(dir, { withFileTypes: true });\n for (const it of items) {\n if (it.isFile() && extname(it.name).toLowerCase() === \".astro\") {\n const abs = join(dir, it.name);\n const relFromComponents = path\n .relative(componentsDir, abs)\n .split(path.sep)\n .join(pathPosix.sep);\n found.push(relFromComponents);\n }\n }\n } catch {}\n }\n return found;\n}\n\nexport function createSourceFileFromFrontmatter(\n frontmatterCode: string,\n): SourceFile {\n const project = new Project({ useInMemoryFileSystem: true });\n return project.createSourceFile(\"Component.ts\", frontmatterCode, {\n overwrite: true,\n });\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bejamas",
3
- "version": "0.2.4",
3
+ "version": "0.2.5",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "bin": {
@@ -1 +0,0 @@
1
- {"version":3,"file":"utils-BXyPCddm.js","names":["BUILTIN_REGISTRIES: z.infer<typeof registryConfigSchema>","fs","type: ProjectInfo","fs","resolvedAliases: any","key","RESERVED_COMPONENTS: Set<string>","meta: Record<string, any>","usageLines: string[]","examplesLines: string[]","primaryExampleLines: string[]","descriptionBodyLines: string[]","current: any","nameNode: any","defaultValue: string | undefined","match: RegExpExecArray | null","found: string[]","pathPosix"],"sources":["../src/registry/constants.ts","../src/utils/highlighter.ts","../src/utils/logger.ts","../src/utils/spinner.ts","../src/utils/get-package-info.ts","../src/utils/get-project-info.ts","../src/utils/resolve-import.ts","../src/utils/get-config.ts","../src/docs/generate-mdx/utils.ts"],"sourcesContent":["import { registryConfigSchema } from \"shadcn/schema\";\nimport { z } from \"zod\";\n\nexport const REGISTRY_URL =\n process.env.REGISTRY_URL ?? \"http://localhost:4321/r\";\n\nexport const FALLBACK_STYLE = \"new-york-v4\";\n\nexport const BASE_COLORS = [\n {\n name: \"neutral\",\n label: \"Neutral\",\n },\n {\n name: \"gray\",\n label: \"Gray\",\n },\n {\n name: \"zinc\",\n label: \"Zinc\",\n },\n {\n name: \"stone\",\n label: \"Stone\",\n },\n {\n name: \"slate\",\n label: \"Slate\",\n },\n] as const;\n\n// Built-in registries that are always available and cannot be overridden\nexport const BUILTIN_REGISTRIES: z.infer<typeof registryConfigSchema> = {\n \"@bejamas\": `${REGISTRY_URL}/{name}.json`,\n};\n\nexport const BUILTIN_MODULES = new Set([\n [\n // Node.js built-in modules\n // From https://github.com/sindresorhus/builtin-modules.\n \"node:assert\",\n \"assert\",\n \"node:assert/strict\",\n \"assert/strict\",\n \"node:async_hooks\",\n \"async_hooks\",\n \"node:buffer\",\n \"buffer\",\n \"node:child_process\",\n \"child_process\",\n \"node:cluster\",\n \"cluster\",\n \"node:console\",\n \"console\",\n \"node:constants\",\n \"constants\",\n \"node:crypto\",\n \"crypto\",\n \"node:dgram\",\n \"dgram\",\n \"node:diagnostics_channel\",\n \"diagnostics_channel\",\n \"node:dns\",\n \"dns\",\n \"node:dns/promises\",\n \"dns/promises\",\n \"node:domain\",\n \"domain\",\n \"node:events\",\n \"events\",\n \"node:fs\",\n \"fs\",\n \"node:fs/promises\",\n \"fs/promises\",\n \"node:http\",\n \"http\",\n \"node:http2\",\n \"http2\",\n \"node:https\",\n \"https\",\n \"node:inspector\",\n \"inspector\",\n \"node:inspector/promises\",\n \"inspector/promises\",\n \"node:module\",\n \"module\",\n \"node:net\",\n \"net\",\n \"node:os\",\n \"os\",\n \"node:path\",\n \"path\",\n \"node:path/posix\",\n \"path/posix\",\n \"node:path/win32\",\n \"path/win32\",\n \"node:perf_hooks\",\n \"perf_hooks\",\n \"node:process\",\n \"process\",\n \"node:querystring\",\n \"querystring\",\n \"node:quic\",\n \"node:readline\",\n \"readline\",\n \"node:readline/promises\",\n \"readline/promises\",\n \"node:repl\",\n \"repl\",\n \"node:sea\",\n \"node:sqlite\",\n \"node:stream\",\n \"stream\",\n \"node:stream/consumers\",\n \"stream/consumers\",\n \"node:stream/promises\",\n \"stream/promises\",\n \"node:stream/web\",\n \"stream/web\",\n \"node:string_decoder\",\n \"string_decoder\",\n \"node:test\",\n \"node:test/reporters\",\n \"node:timers\",\n \"timers\",\n \"node:timers/promises\",\n \"timers/promises\",\n \"node:tls\",\n \"tls\",\n \"node:trace_events\",\n \"trace_events\",\n \"node:tty\",\n \"tty\",\n \"node:url\",\n \"url\",\n \"node:util\",\n \"util\",\n \"node:util/types\",\n \"util/types\",\n \"node:v8\",\n \"v8\",\n \"node:vm\",\n \"vm\",\n \"node:wasi\",\n \"wasi\",\n \"node:worker_threads\",\n \"worker_threads\",\n \"node:zlib\",\n \"zlib\",\n\n // Bun built-in modules.\n \"bun\",\n \"bun:test\",\n \"bun:sqlite\",\n \"bun:ffi\",\n \"bun:jsc\",\n \"bun:internal\",\n ],\n]);\n\nexport const DEPRECATED_COMPONENTS = [\n {\n name: \"toast\",\n deprecatedBy: \"sonner\",\n message:\n \"The toast component is deprecated. Use the sonner component instead.\",\n },\n {\n name: \"toaster\",\n deprecatedBy: \"sonner\",\n message:\n \"The toaster component is deprecated. Use the sonner component instead.\",\n },\n];\n","import { cyan, green, red, yellow } from \"kleur/colors\";\n\nexport const highlighter = {\n error: red,\n warn: yellow,\n info: cyan,\n success: green,\n};\n","import { highlighter } from \"@/src/utils/highlighter\";\n\nexport const logger = {\n error(...args: unknown[]) {\n console.log(highlighter.error(args.join(\" \")));\n },\n warn(...args: unknown[]) {\n console.log(highlighter.warn(args.join(\" \")));\n },\n info(...args: unknown[]) {\n console.log(highlighter.info(args.join(\" \")));\n },\n success(...args: unknown[]) {\n console.log(highlighter.success(args.join(\" \")));\n },\n log(...args: unknown[]) {\n console.log(args.join(\" \"));\n },\n break() {\n console.log(\"\");\n },\n};\n","import ora, { type Options } from \"ora\";\n\nexport function spinner(\n text: Options[\"text\"],\n options?: {\n silent?: boolean;\n },\n) {\n return ora({\n text,\n isSilent: options?.silent,\n });\n}\n","import path from \"path\";\nimport fs from \"fs-extra\";\nimport { type PackageJson } from \"type-fest\";\n\nexport function getPackageInfo(\n cwd: string = \"\",\n shouldThrow: boolean = true,\n): PackageJson | null {\n const packageJsonPath = path.join(cwd, \"package.json\");\n\n return fs.readJSONSync(packageJsonPath, {\n throws: shouldThrow,\n }) as PackageJson;\n}\n","import path from \"path\";\nimport { rawConfigSchema } from \"shadcn/schema\";\nimport { Config, getConfig, resolveConfigPaths } from \"@/src/utils/get-config\";\nimport { getPackageInfo } from \"@/src/utils/get-package-info\";\nimport fg from \"fast-glob\";\nimport fs from \"fs-extra\";\nimport { loadConfig } from \"tsconfig-paths\";\nimport { z } from \"zod\";\n\nexport type TailwindVersion = \"v3\" | \"v4\" | null;\n\nexport type ProjectInfo = {\n isAstro: boolean;\n tailwindConfigFile: string | null;\n tailwindCssFile: string | null;\n tailwindVersion: TailwindVersion;\n aliasPrefix: string | null;\n};\n\nconst PROJECT_SHARED_IGNORE = [\n \"**/node_modules/**\",\n \".astro\",\n \"public\",\n \"dist\",\n \"build\",\n];\n\nconst TS_CONFIG_SCHEMA = z.object({\n compilerOptions: z.object({\n paths: z.record(z.string().or(z.array(z.string()))),\n }),\n});\n\nexport async function getProjectInfo(cwd: string): Promise<ProjectInfo | null> {\n const [\n configFiles,\n tailwindConfigFile,\n tailwindCssFile,\n tailwindVersion,\n aliasPrefix,\n packageJson,\n ] = await Promise.all([\n fg.glob(\n \"**/{next,vite,astro,app}.config.*|gatsby-config.*|composer.json|react-router.config.*\",\n {\n cwd,\n deep: 3,\n ignore: PROJECT_SHARED_IGNORE,\n },\n ),\n getTailwindConfigFile(cwd),\n getTailwindCssFile(cwd),\n getTailwindVersion(cwd),\n getTsConfigAliasPrefix(cwd),\n getPackageInfo(cwd, false),\n ]);\n\n const type: ProjectInfo = {\n isAstro: false,\n tailwindConfigFile,\n tailwindCssFile,\n tailwindVersion,\n aliasPrefix,\n };\n\n // Astro.\n if (configFiles.find((file) => file.startsWith(\"astro.config.\"))?.length) {\n type.isAstro = true;\n return type;\n }\n\n return type;\n}\n\nexport async function getTailwindVersion(\n cwd: string,\n): Promise<ProjectInfo[\"tailwindVersion\"]> {\n const [packageInfo, config] = await Promise.all([\n getPackageInfo(cwd, false),\n getConfig(cwd),\n ]);\n\n // If the config file is empty, we can assume that it's a v4 project.\n if (config?.tailwind?.config === \"\") {\n return \"v4\";\n }\n\n if (\n !packageInfo?.dependencies?.tailwindcss &&\n !packageInfo?.devDependencies?.tailwindcss\n ) {\n return null;\n }\n\n if (\n /^(?:\\^|~)?3(?:\\.\\d+)*(?:-.*)?$/.test(\n packageInfo?.dependencies?.tailwindcss ||\n packageInfo?.devDependencies?.tailwindcss ||\n \"\",\n )\n ) {\n return \"v3\";\n }\n\n return \"v4\";\n}\n\nexport async function getTailwindCssFile(cwd: string) {\n const [files, tailwindVersion] = await Promise.all([\n fg.glob([\"**/*.css\", \"**/*.scss\"], {\n cwd,\n deep: 5,\n ignore: PROJECT_SHARED_IGNORE,\n }),\n getTailwindVersion(cwd),\n ]);\n\n if (!files.length) {\n return null;\n }\n\n const needle =\n tailwindVersion === \"v4\" ? `@import \"tailwindcss\"` : \"@tailwind base\";\n for (const file of files) {\n const contents = await fs.readFile(path.resolve(cwd, file), \"utf8\");\n if (\n contents.includes(`@import \"tailwindcss\"`) ||\n contents.includes(`@import 'tailwindcss'`) ||\n contents.includes(`@tailwind base`)\n ) {\n return file;\n }\n }\n\n return null;\n}\n\nexport async function getTailwindConfigFile(cwd: string) {\n const files = await fg.glob(\"tailwind.config.*\", {\n cwd,\n deep: 3,\n ignore: PROJECT_SHARED_IGNORE,\n });\n\n if (!files.length) {\n return null;\n }\n\n return files[0];\n}\n\nexport async function getTsConfigAliasPrefix(cwd: string) {\n const tsConfig = await loadConfig(cwd);\n\n if (\n tsConfig?.resultType === \"failed\" ||\n !Object.entries(tsConfig?.paths).length\n ) {\n return null;\n }\n\n // This assume that the first alias is the prefix.\n for (const [alias, paths] of Object.entries(tsConfig.paths)) {\n if (\n paths.includes(\"./*\") ||\n paths.includes(\"./src/*\") ||\n paths.includes(\"./app/*\") ||\n paths.includes(\"./resources/js/*\") // Laravel.\n ) {\n return alias.replace(/\\/\\*$/, \"\") ?? null;\n }\n }\n\n // Use the first alias as the prefix.\n return Object.keys(tsConfig?.paths)?.[0].replace(/\\/\\*$/, \"\") ?? null;\n}\n\nexport async function isTypeScriptProject(cwd: string) {\n const files = await fg.glob(\"tsconfig.*\", {\n cwd,\n deep: 1,\n ignore: PROJECT_SHARED_IGNORE,\n });\n\n return files.length > 0;\n}\n\nexport async function getTsConfig(cwd: string) {\n for (const fallback of [\n \"tsconfig.json\",\n \"tsconfig.web.json\",\n \"tsconfig.app.json\",\n ]) {\n const filePath = path.resolve(cwd, fallback);\n if (!(await fs.pathExists(filePath))) {\n continue;\n }\n\n // We can't use fs.readJSON because it doesn't support comments.\n const contents = await fs.readFile(filePath, \"utf8\");\n const cleanedContents = contents.replace(/\\/\\*\\s*\\*\\//g, \"\");\n const result = TS_CONFIG_SCHEMA.safeParse(JSON.parse(cleanedContents));\n\n if (result.error) {\n continue;\n }\n\n return result.data;\n }\n\n return null;\n}\n\nexport async function getProjectConfig(\n cwd: string,\n defaultProjectInfo: ProjectInfo | null = null,\n): Promise<Config | null> {\n // Check for existing component config.\n const [existingConfig, projectInfo] = await Promise.all([\n getConfig(cwd),\n !defaultProjectInfo\n ? getProjectInfo(cwd)\n : Promise.resolve(defaultProjectInfo),\n ]);\n\n if (existingConfig) {\n return existingConfig;\n }\n\n if (\n !projectInfo ||\n !projectInfo.tailwindCssFile ||\n (projectInfo.tailwindVersion === \"v3\" && !projectInfo.tailwindConfigFile)\n ) {\n return null;\n }\n\n const config: z.infer<typeof rawConfigSchema> = {\n $schema: \"https://ui.shadcn.com/schema.json\",\n style: \"new-york\",\n tailwind: {\n config: projectInfo.tailwindConfigFile ?? \"\",\n baseColor: \"zinc\",\n css: projectInfo.tailwindCssFile,\n cssVariables: true,\n prefix: \"\",\n },\n iconLibrary: \"lucide\",\n aliases: {\n components: `${projectInfo.aliasPrefix}/components`,\n ui: `${projectInfo.aliasPrefix}/components/ui`,\n lib: `${projectInfo.aliasPrefix}/lib`,\n utils: `${projectInfo.aliasPrefix}/lib/utils`,\n },\n };\n\n return await resolveConfigPaths(cwd, config);\n}\n\nexport async function getProjectTailwindVersionFromConfig(config: {\n resolvedPaths: Pick<Config[\"resolvedPaths\"], \"cwd\">;\n}): Promise<TailwindVersion> {\n if (!config.resolvedPaths?.cwd) {\n return \"v3\";\n }\n\n const projectInfo = await getProjectInfo(config.resolvedPaths.cwd);\n\n if (!projectInfo?.tailwindVersion) {\n return null;\n }\n\n return projectInfo.tailwindVersion;\n}\n","import {\n createMatchPath,\n type ConfigLoaderSuccessResult,\n} from \"tsconfig-paths\";\n\nexport async function resolveImport(\n importPath: string,\n config: Pick<ConfigLoaderSuccessResult, \"absoluteBaseUrl\" | \"paths\">,\n) {\n return createMatchPath(config.absoluteBaseUrl, config.paths)(\n importPath,\n undefined,\n () => true,\n [\".ts\", \".tsx\", \".jsx\", \".js\", \".css\"],\n );\n}\n","import path from \"path\";\nimport { BUILTIN_REGISTRIES } from \"@/src/registry/constants\";\nimport {\n configSchema,\n rawConfigSchema,\n workspaceConfigSchema,\n} from \"shadcn/schema\";\nimport { getProjectInfo } from \"@/src/utils/get-project-info\";\nimport { highlighter } from \"@/src/utils/highlighter\";\nimport { resolveImport } from \"@/src/utils/resolve-import\";\nimport { cosmiconfig } from \"cosmiconfig\";\nimport fg from \"fast-glob\";\nimport { loadConfig } from \"tsconfig-paths\";\nimport { z } from \"zod\";\n\nexport const DEFAULT_STYLE = \"default\";\nexport const DEFAULT_COMPONENTS = \"@/components\";\nexport const DEFAULT_UTILS = \"@/lib/utils\";\nexport const DEFAULT_TAILWIND_CSS = \"app/globals.css\";\nexport const DEFAULT_TAILWIND_CONFIG = \"tailwind.config.js\";\nexport const DEFAULT_TAILWIND_BASE_COLOR = \"slate\";\n\n// TODO: Figure out if we want to support all cosmiconfig formats.\n// A simple components.json file would be nice.\nexport const explorer = cosmiconfig(\"components\", {\n searchPlaces: [\"components.json\"],\n});\n\nexport type Config = z.infer<typeof configSchema>;\n\nexport async function getConfig(cwd: string) {\n const config = await getRawConfig(cwd);\n\n if (!config) {\n return null;\n }\n\n // Set default icon library if not provided.\n if (!config.iconLibrary) {\n config.iconLibrary = config.style === \"new-york\" ? \"radix\" : \"lucide\";\n }\n\n return await resolveConfigPaths(cwd, config);\n}\n\nexport async function resolveConfigPaths(\n cwd: string,\n config: z.infer<typeof rawConfigSchema>,\n) {\n // Merge built-in registries with user registries\n config.registries = {\n ...BUILTIN_REGISTRIES,\n ...(config.registries || {}),\n };\n\n // Read tsconfig.json.\n const tsConfig = await loadConfig(cwd);\n\n if (tsConfig.resultType === \"failed\") {\n throw new Error(\n `Failed to load ${config.tsx ? \"tsconfig\" : \"jsconfig\"}.json. ${\n tsConfig.message ?? \"\"\n }`.trim(),\n );\n }\n\n return configSchema.parse({\n ...config,\n resolvedPaths: {\n cwd,\n tailwindConfig: config.tailwind.config\n ? path.resolve(cwd, config.tailwind.config)\n : \"\",\n tailwindCss: path.resolve(cwd, config.tailwind.css),\n utils: await resolveImport(config.aliases[\"utils\"], tsConfig),\n components: await resolveImport(config.aliases[\"components\"], tsConfig),\n ui: config.aliases[\"ui\"]\n ? await resolveImport(config.aliases[\"ui\"], tsConfig)\n : path.resolve(\n (await resolveImport(config.aliases[\"components\"], tsConfig)) ??\n cwd,\n \"ui\",\n ),\n // TODO: Make this configurable.\n // For now, we assume the lib and hooks directories are one level up from the components directory.\n lib: config.aliases[\"lib\"]\n ? await resolveImport(config.aliases[\"lib\"], tsConfig)\n : path.resolve(\n (await resolveImport(config.aliases[\"utils\"], tsConfig)) ?? cwd,\n \"..\",\n ),\n hooks: config.aliases[\"hooks\"]\n ? await resolveImport(config.aliases[\"hooks\"], tsConfig)\n : path.resolve(\n (await resolveImport(config.aliases[\"components\"], tsConfig)) ??\n cwd,\n \"..\",\n \"hooks\",\n ),\n },\n });\n}\n\nexport async function getRawConfig(\n cwd: string,\n): Promise<z.infer<typeof rawConfigSchema> | null> {\n try {\n const configResult = await explorer.search(cwd);\n\n if (!configResult) {\n return null;\n }\n\n const config = rawConfigSchema.parse(configResult.config);\n\n // Check if user is trying to override built-in registries\n if (config.registries) {\n for (const registryName of Object.keys(config.registries)) {\n if (registryName in BUILTIN_REGISTRIES) {\n throw new Error(\n `\"${registryName}\" is a built-in registry and cannot be overridden.`,\n );\n }\n }\n }\n\n return config;\n } catch (error) {\n const componentPath = `${cwd}/components.json`;\n if (error instanceof Error && error.message.includes(\"reserved registry\")) {\n throw error;\n }\n throw new Error(\n `Invalid configuration found in ${highlighter.info(componentPath)}.`,\n );\n }\n}\n\n// Note: we can check for -workspace.yaml or \"workspace\" in package.json.\n// Since cwd is not necessarily the root of the project.\n// We'll instead check if ui aliases resolve to a different root.\nexport async function getWorkspaceConfig(config: Config) {\n let resolvedAliases: any = {};\n\n for (const key of Object.keys(config.aliases)) {\n if (!isAliasKey(key, config)) {\n continue;\n }\n\n const resolvedPath = config.resolvedPaths[key];\n const packageRoot = await findPackageRoot(\n config.resolvedPaths.cwd,\n resolvedPath,\n );\n\n if (!packageRoot) {\n resolvedAliases[key] = config;\n continue;\n }\n\n resolvedAliases[key] = await getConfig(packageRoot);\n }\n\n const result = workspaceConfigSchema.safeParse(resolvedAliases);\n if (!result.success) {\n return null;\n }\n\n return result.data;\n}\n\nexport async function findPackageRoot(cwd: string, resolvedPath: string) {\n const commonRoot = findCommonRoot(cwd, resolvedPath);\n const relativePath = path.relative(commonRoot, resolvedPath);\n\n const packageRoots = await fg.glob(\"**/package.json\", {\n cwd: commonRoot,\n deep: 3,\n ignore: [\"**/node_modules/**\", \"**/dist/**\", \"**/build/**\", \"**/public/**\"],\n });\n\n const matchingPackageRoot = packageRoots\n .map((pkgPath) => path.dirname(pkgPath))\n .find((pkgDir) => relativePath.startsWith(pkgDir));\n\n return matchingPackageRoot\n ? path.join(commonRoot, matchingPackageRoot)\n : null;\n}\n\nfunction isAliasKey(\n key: string,\n config: Config,\n): key is keyof Config[\"aliases\"] {\n return Object.keys(config.resolvedPaths)\n .filter((key) => key !== \"utils\")\n .includes(key);\n}\n\nexport function findCommonRoot(cwd: string, resolvedPath: string) {\n const parts1 = cwd.split(path.sep);\n const parts2 = resolvedPath.split(path.sep);\n const commonParts = [];\n\n for (let i = 0; i < Math.min(parts1.length, parts2.length); i++) {\n if (parts1[i] !== parts2[i]) {\n break;\n }\n commonParts.push(parts1[i]);\n }\n\n return commonParts.join(path.sep);\n}\n\n// TODO: Cache this call.\nexport async function getTargetStyleFromConfig(cwd: string, fallback: string) {\n const projectInfo = await getProjectInfo(cwd);\n return projectInfo?.tailwindVersion === \"v4\" ? \"new-york-v4\" : fallback;\n}\n\ntype DeepPartial<T> = {\n [P in keyof T]?: T[P] extends object ? DeepPartial<T[P]> : T[P];\n};\n\n/**\n * Creates a config object with sensible defaults.\n * Useful for universal registry items that bypass framework detection.\n *\n * @param partial - Partial config values to override defaults\n * @returns A complete Config object\n */\nexport function createConfig(partial?: DeepPartial<Config>): Config {\n const defaultConfig: Config = {\n resolvedPaths: {\n cwd: process.cwd(),\n tailwindConfig: \"\",\n tailwindCss: \"\",\n utils: \"\",\n components: \"\",\n ui: \"\",\n lib: \"\",\n hooks: \"\",\n },\n style: \"\",\n tailwind: {\n config: \"\",\n css: \"\",\n baseColor: \"\",\n cssVariables: false,\n },\n rsc: false,\n tsx: true,\n aliases: {\n components: \"\",\n utils: \"\",\n },\n registries: {\n ...BUILTIN_REGISTRIES,\n },\n };\n\n // Deep merge the partial config with defaults\n if (partial) {\n return {\n ...defaultConfig,\n ...partial,\n resolvedPaths: {\n ...defaultConfig.resolvedPaths,\n ...(partial.resolvedPaths || {}),\n },\n tailwind: {\n ...defaultConfig.tailwind,\n ...(partial.tailwind || {}),\n },\n aliases: {\n ...defaultConfig.aliases,\n ...(partial.aliases || {}),\n },\n registries: {\n ...defaultConfig.registries,\n ...(partial.registries || {}),\n },\n };\n }\n\n return defaultConfig;\n}\n","import { existsSync, readFileSync } from \"fs\";\nimport { readdir } from \"fs/promises\";\nimport path, { dirname, extname, join, posix as pathPosix } from \"path\";\nimport { createRequire } from \"module\";\nimport { Project, SyntaxKind, SourceFile } from \"ts-morph\";\n\nexport const RESERVED_COMPONENTS: Set<string> = new Set([\n \"Fragment\",\n \"CodePackageManagers\",\n \"DocsTabs\",\n \"DocsTabItem\",\n \"DocsCodePackageManagers\",\n \"Tabs\",\n \"TabItem\",\n]);\n\nexport function slugify(input: string): string {\n return input\n .replace(/\\.(astro|md|mdx|tsx|ts|jsx|js)$/i, \"\")\n .replace(/([a-z0-9])([A-Z])/g, \"$1-$2\")\n .replace(/\\s+/g, \"-\")\n .replace(/_+/g, \"-\")\n .toLowerCase();\n}\n\nexport function extractFrontmatter(source: string): string {\n const match = source.match(/^---\\n([\\s\\S]*?)\\n---/);\n return (match && match[1]) || \"\";\n}\n\nexport function toIdentifier(name: string): string {\n const base = name\n .replace(/\\.[^.]+$/, \"\")\n .replace(/[^a-zA-Z0-9]+/g, \" \")\n .trim()\n .replace(/\\b\\w/g, (c) => c.toUpperCase())\n .replace(/\\s+/g, \"\");\n return /^[A-Za-z_]/.test(base) ? base : `Ex${base}`;\n}\n\nexport function parseJsDocMetadata(\n frontmatterCode: string,\n): Record<string, any> {\n const jsDocMatch = frontmatterCode.match(/\\/\\*\\*([\\s\\S]*?)\\*\\//);\n if (!jsDocMatch) return {};\n const content = jsDocMatch[1];\n const lines = content.split(\"\\n\").map((l) => l.replace(/^\\s*\\*\\s?/, \"\"));\n const meta: Record<string, any> = {};\n let inUsage = false;\n let inExamples = false;\n let inPrimaryExample = false;\n let captureDescriptionBody = false;\n const usageLines: string[] = [];\n const examplesLines: string[] = [];\n const primaryExampleLines: string[] = [];\n const descriptionBodyLines: string[] = [];\n for (const rawLine of lines) {\n const line = rawLine;\n if (inUsage) {\n if (line.trim().startsWith(\"@\")) {\n inUsage = false;\n } else {\n usageLines.push(line);\n continue;\n }\n }\n if (inPrimaryExample) {\n if (line.trim().startsWith(\"@\")) {\n inPrimaryExample = false;\n } else {\n primaryExampleLines.push(line);\n continue;\n }\n }\n if (inExamples) {\n if (line.trim().startsWith(\"@\")) {\n inExamples = false;\n } else {\n examplesLines.push(line);\n continue;\n }\n }\n if (captureDescriptionBody) {\n if (line.trim().startsWith(\"@\")) {\n captureDescriptionBody = false;\n } else {\n descriptionBodyLines.push(line);\n continue;\n }\n }\n if (line.trim().startsWith(\"@component\"))\n meta.name = line.replace(\"@component\", \"\").trim();\n else if (line.trim().startsWith(\"@title\"))\n meta.title = line.replace(\"@title\", \"\").trim();\n else if (line.trim().startsWith(\"@description\")) {\n meta.description = line.replace(\"@description\", \"\").trim();\n captureDescriptionBody = true;\n continue;\n } else if (line.trim().startsWith(\"@figmaUrl\"))\n meta.figmaUrl = line.replace(\"@figmaUrl\", \"\").trim();\n // Backward compatibility: support @figma but map to figmaUrl\n else if (line.trim().startsWith(\"@figma\"))\n meta.figmaUrl = line.replace(\"@figma\", \"\").trim();\n else if (line.trim().startsWith(\"@usage\")) {\n inUsage = true;\n continue;\n } else if (line.trim().startsWith(\"@examples\")) {\n inExamples = true;\n continue;\n } else if (line.trim().startsWith(\"@preview\")) {\n inPrimaryExample = true;\n continue;\n } else if (line.trim().startsWith(\"@example\")) {\n // backward compatibility with older docs\n inPrimaryExample = true;\n continue;\n }\n }\n if (usageLines.length) meta.usageMDX = usageLines.join(\"\\n\").trim();\n if (examplesLines.length) meta.examplesMDX = examplesLines.join(\"\\n\").trim();\n if (primaryExampleLines.length)\n meta.primaryExampleMDX = primaryExampleLines.join(\"\\n\").trim();\n if (descriptionBodyLines.length)\n meta.descriptionBodyMDX = descriptionBodyLines.join(\"\\n\").trim();\n return meta;\n}\n\nexport function extractPropsFromAstroProps(sourceFile: SourceFile): Array<{\n name?: string;\n isRest?: boolean;\n hasDefault?: boolean;\n defaultValue?: string;\n alias?: string;\n}> {\n // Helper: unwrap expressions like `(Astro.props as Props)`, `Astro.props as Props`,\n // `<Props>Astro.props`, `(Astro.props)!`, and parenthesized variants until we reach\n // the underlying PropertyAccessExpression.\n function unwrapAstroProps(node: any): any | null {\n let current: any = node;\n // Unwrap layers that can wrap the property access\n // AsExpression, TypeAssertion, SatisfiesExpression, NonNullExpression, ParenthesizedExpression\n // Keep drilling down via getExpression()\n // Guard against cycles by limiting iterations\n for (let i = 0; i < 10; i += 1) {\n const kind = current.getKind();\n if (kind === SyntaxKind.PropertyAccessExpression) {\n const expr = current.getExpression();\n if (\n expr &&\n expr.getText() === \"Astro\" &&\n current.getName() === \"props\"\n ) {\n return current;\n }\n return null;\n }\n if (\n kind === SyntaxKind.AsExpression ||\n kind === SyntaxKind.TypeAssertion ||\n // @ts-ignore - SatisfiesExpression may not exist in older TS versions\n kind === (SyntaxKind as any).SatisfiesExpression ||\n kind === SyntaxKind.NonNullExpression ||\n kind === SyntaxKind.ParenthesizedExpression\n ) {\n const next = current.getExpression && current.getExpression();\n if (!next) return null;\n current = next;\n continue;\n }\n return null;\n }\n return null;\n }\n\n const declarations = sourceFile.getDescendantsOfKind(\n SyntaxKind.VariableDeclaration,\n );\n const target = declarations.find((decl) => {\n const init = decl.getInitializer();\n if (!init) return false;\n return !!unwrapAstroProps(init);\n });\n if (!target) return [];\n const nameNode: any = target.getNameNode();\n if (!nameNode || nameNode.getKind() !== SyntaxKind.ObjectBindingPattern)\n return [];\n const obj = nameNode.asKindOrThrow(SyntaxKind.ObjectBindingPattern);\n return obj.getElements().map((el: any) => {\n const isRest = !!el.getDotDotDotToken();\n if (isRest) return { isRest: true, hasDefault: false, alias: el.getName() };\n const propertyNameNode = el.getPropertyNameNode();\n const name = el.getName();\n const propName = propertyNameNode ? propertyNameNode.getText() : name;\n const initializer = el.getInitializer();\n let defaultValue: string | undefined;\n if (initializer) defaultValue = initializer.getText();\n return { name: propName, hasDefault: initializer != null, defaultValue };\n });\n}\n\nexport function extractPropsFromDeclaredProps(sourceFile: SourceFile): Array<{\n name: string;\n type: string;\n optional: boolean;\n}> {\n function normalizeTypeText(text: string | undefined): string {\n if (!text) return \"\";\n return text.replace(/\\s+/g, \" \").replace(/;\\s*$/, \"\").trim();\n }\n // Prefer interface Props\n const iface = sourceFile.getInterface(\"Props\");\n if (iface) {\n const properties = iface.getProperties();\n return properties.map((prop) => {\n const name = prop.getName();\n const typeNode = prop.getTypeNode();\n const rawType = typeNode ? typeNode.getText() : prop.getType().getText();\n const typeText = normalizeTypeText(rawType);\n const optional = prop.hasQuestionToken();\n return { name, type: typeText, optional };\n });\n }\n\n // Fallback: type Props = { ... }\n const typeAlias = sourceFile.getTypeAlias(\"Props\");\n if (typeAlias) {\n const typeNode = typeAlias.getTypeNode();\n if (typeNode && typeNode.getKind() === SyntaxKind.TypeLiteral) {\n const literal = typeNode.asKindOrThrow(SyntaxKind.TypeLiteral);\n const properties = literal.getProperties();\n return properties.map((prop) => {\n const name = prop.getName();\n const tn = prop.getTypeNode();\n const rawType = tn ? tn.getText() : prop.getType().getText();\n const typeText = normalizeTypeText(rawType);\n const optional = prop.hasQuestionToken();\n return { name, type: typeText, optional };\n });\n }\n }\n\n return [];\n}\n\nexport function resolveUiRoot(cwd: string): string {\n const require = createRequire(import.meta.url);\n\n const envRoot = process.env.BEJAMAS_UI_ROOT;\n if (envRoot && existsSync(path.join(envRoot, \"package.json\"))) {\n return envRoot;\n }\n\n try {\n const pkgPath = require.resolve(\"@bejamas/ui/package.json\", {\n paths: [cwd],\n });\n return path.dirname(pkgPath);\n } catch {}\n\n let current = cwd;\n for (let i = 0; i < 6; i += 1) {\n const candidate = path.join(current, \"packages\", \"ui\", \"package.json\");\n if (existsSync(candidate)) return path.dirname(candidate);\n const parent = path.dirname(current);\n if (parent === current) break;\n current = parent;\n }\n\n try {\n const anyEntry = require.resolve(\"@bejamas/ui/*\", { paths: [cwd] });\n return path.resolve(anyEntry, \"..\", \"..\");\n } catch {}\n\n throw new Error(\"Unable to locate @bejamas/ui in the workspace\");\n}\n\nexport function resolveOutDir(cwd: string): string {\n const envOut = process.env.BEJAMAS_DOCS_OUT_DIR;\n if (envOut && envOut.length) {\n return path.isAbsolute(envOut) ? envOut : path.resolve(cwd, envOut);\n }\n return path.resolve(cwd, \"../../apps/web/src/content/docs/components\");\n}\n\nexport function detectHasImportTopLevel(\n block: string,\n pascalName: string,\n): boolean {\n if (!block) return false;\n let inFence = false;\n const importLineRegex = new RegExp(\n `^\\\\s*import\\\\s+.*\\\\bfrom\\\\s+['\"][^'\"]+\\\\b${pascalName}\\\\.astro['\"]`,\n );\n for (const line of block.split(\"\\n\")) {\n const trimmed = line.trim();\n if (trimmed.startsWith(\"```\")) {\n inFence = !inFence;\n continue;\n }\n if (!inFence && importLineRegex.test(line)) return true;\n }\n return false;\n}\n\nexport function hasImportOfTopLevel(\n block: string,\n componentName: string,\n): boolean {\n if (!block) return false;\n let inFence = false;\n const importRegex = new RegExp(\n `^\\\\s*import\\\\s+[^;]*\\\\b${componentName}\\\\b[^;]*from\\\\s+['\"][^'\"]*(?:/|^)${componentName}\\\\.astro['\"]`,\n );\n const lucideIconRegex = /Icon$/.test(componentName)\n ? new RegExp(\n `^\\\\s*import\\\\s+\\\\{[^}]*\\\\b${componentName}\\\\b[^}]*\\\\}\\\\s+from\\\\s+['\"]@lucide/astro['\"]`,\n )\n : null;\n for (const line of block.split(\"\\n\")) {\n const trimmed = line.trim();\n if (trimmed.startsWith(\"```\")) {\n inFence = !inFence;\n continue;\n }\n if (!inFence && importRegex.test(line)) return true;\n if (!inFence && lucideIconRegex && lucideIconRegex.test(line)) return true;\n }\n return false;\n}\n\nexport function normalizeBlockMDX(block: string): string {\n if (!block) return \"\";\n return block.replace(\n /from\\s+['\"]@\\/ui\\/components\\//g,\n \"from '@bejamas/ui/components/\",\n );\n}\n\nexport function replaceDocsComponentTags(block: string): string {\n if (!block) return \"\";\n let inFence = false;\n const lines = block.split(\"\\n\");\n const out: string[] = [];\n for (const line of lines) {\n const trimmed = line.trim();\n if (trimmed.startsWith(\"```\")) {\n inFence = !inFence;\n out.push(line);\n continue;\n }\n if (inFence) {\n out.push(line);\n continue;\n }\n const replaced = line\n .replace(/<Tabs(\\b|\\s)/g, \"<DocsTabs$1\")\n .replace(/<\\/Tabs>/g, \"</DocsTabs>\")\n .replace(/<TabItem(\\b|\\s)/g, \"<DocsTabItem$1\")\n .replace(/<\\/TabItem>/g, \"</DocsTabItem>\");\n out.push(replaced);\n }\n return out.join(\"\\n\");\n}\n\nexport function normalizeUsageMDX(\n usageMDX: string,\n pascalName: string,\n): { text: string; hasImport: boolean } {\n const normalized = normalizeBlockMDX(usageMDX);\n const hasImport = detectHasImportTopLevel(normalized, pascalName);\n return { text: normalized.trim(), hasImport };\n}\n\nexport function extractComponentTagsFromMDX(block: string): string[] {\n if (!block) return [];\n let inFence = false;\n const found = new Set<string>();\n const tagRegex = /<([A-Z][A-Za-z0-9_]*)\\b/g;\n for (const line of block.split(\"\\n\")) {\n const trimmed = line.trim();\n if (trimmed.startsWith(\"```\")) {\n inFence = !inFence;\n continue;\n }\n if (inFence) continue;\n let match: RegExpExecArray | null;\n while ((match = tagRegex.exec(line)) !== null) {\n const name = match[1];\n found.add(name);\n }\n }\n return Array.from(found);\n}\n\nexport async function discoverExamples(\n componentFilePath: string,\n componentsDir: string,\n): Promise<string[]> {\n const fileBase = path.basename(\n componentFilePath,\n path.extname(componentFilePath),\n );\n const kebabBase = slugify(fileBase);\n const candidates = [\n join(dirname(componentFilePath), `${fileBase}.examples`),\n join(dirname(componentFilePath), `${kebabBase}.examples`),\n ];\n const found: string[] = [];\n for (const dir of candidates) {\n try {\n const items = await readdir(dir, { withFileTypes: true });\n for (const it of items) {\n if (it.isFile() && extname(it.name).toLowerCase() === \".astro\") {\n const abs = join(dir, it.name);\n const relFromComponents = path\n .relative(componentsDir, abs)\n .split(path.sep)\n .join(pathPosix.sep);\n found.push(relFromComponents);\n }\n }\n } catch {}\n }\n return found;\n}\n\nexport function createSourceFileFromFrontmatter(\n frontmatterCode: string,\n): SourceFile {\n const project = new Project({ useInMemoryFileSystem: true });\n return project.createSourceFile(\"Component.ts\", frontmatterCode, {\n overwrite: true,\n });\n}\n"],"mappings":"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"}