@babelize/elements 1.1.2 → 1.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -44,6 +44,23 @@
44
44
  npm install @babelize/elements
45
45
  ```
46
46
 
47
+ Tailwind does not scan `node_modules`, so point it at the package once — otherwise
48
+ the components render unstyled:
49
+
50
+ ```css
51
+ /* Tailwind v4 — in the CSS file that imports Tailwind */
52
+ @import "tailwindcss";
53
+ @source "../node_modules/@babelize/elements/dist";
54
+ ```
55
+
56
+ ```js
57
+ // Tailwind v3 — in tailwind.config.js
58
+ content: ["./src/**/*.{ts,tsx}", "./node_modules/@babelize/elements/dist/**/*.js"],
59
+ ```
60
+
61
+ Components installed with the CLI below live in your own source tree, so they need
62
+ no extra Tailwind config.
63
+
47
64
  ### Individual components
48
65
 
49
66
  Install a component with the shadcn CLI (register the registry once):
@@ -68,6 +85,11 @@ and `onValueChange`).
68
85
  import { LanguageSwitcher, PhoneInput, NavBar } from "@babelize/elements";
69
86
  ```
70
87
 
88
+ The components are client components, and the package declares `"use client"` for
89
+ you — importing them from a React Server Component works without any extra wrapper.
90
+ The `cn` helper is also available from `@babelize/elements/utils`, which carries no
91
+ directive and so can be called from server code.
92
+
71
93
  ### LanguageSwitcher
72
94
 
73
95
  ```tsx
@@ -191,6 +213,16 @@ Great component candidates:
191
213
  </a>
192
214
  </p>
193
215
 
216
+ ## Star History
217
+
218
+ <a href="https://www.star-history.com/?repos=babelize%2Fbabelize-elements&type=date&legend=top-right">
219
+ <picture>
220
+ <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=babelize/babelize-elements&type=date&theme=dark&legend=top-left" />
221
+ <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=babelize/babelize-elements&type=date&legend=top-left" />
222
+ <img alt="Star History Chart" src="https://api.star-history.com/chart?repos=babelize/babelize-elements&type=date&legend=top-left" />
223
+ </picture>
224
+ </a>
225
+
194
226
  ## License
195
227
 
196
228
  [MIT](https://github.com/babelize/babelize-elements/blob/main/LICENSE) © [Babelize](https://babelize.co)
package/dist/cli/index.js CHANGED
@@ -40,6 +40,14 @@ function resolveAliasToDir(alias, config) {
40
40
  }
41
41
  return fallback;
42
42
  }
43
+ function resolveFileDestination(filePath, fileType, aliases, config) {
44
+ const toDir = (alias) => resolveAliasToDir(alias, config);
45
+ if (filePath.replace(/^lib\//, "") === "utils.ts") {
46
+ return `${toDir(aliases.utils)}.ts`;
47
+ }
48
+ const dir = fileType === "registry:lib" ? toDir(aliases.lib) : fileType === "registry:hook" ? toDir(aliases.hooks) : fileType === "registry:ui" ? toDir(aliases.ui) : toDir(aliases.components);
49
+ return [dir, filePath.replace(/^(components|lib|ui|hooks)\//, "")].filter(Boolean).join("/");
50
+ }
43
51
 
44
52
  // src/cli/index.ts
45
53
  var REGISTRY_URL = process.env.BABELIZE_REGISTRY ?? "https://elements.babelize.co/r";
@@ -93,9 +101,6 @@ function resolveAliases() {
93
101
  return { ...DEFAULT_ALIASES, ...user };
94
102
  }
95
103
  var tsPaths = readTsPaths();
96
- function aliasToDir(alias) {
97
- return resolveAliasToDir(alias, tsPaths);
98
- }
99
104
  async function fetchItem(nameOrUrl) {
100
105
  const url = /^https?:\/\//.test(nameOrUrl) ? nameOrUrl : `${REGISTRY_URL}/${nameOrUrl}.json`;
101
106
  const res = await fetch(url);
@@ -120,9 +125,7 @@ ${CYAN}Installing dependencies with ${pm}${RESET}`);
120
125
  if (result.status !== 0) process.exit(result.status ?? 1);
121
126
  }
122
127
  function resolveDestination(file, aliases) {
123
- const dir = file.type === "registry:lib" ? aliasToDir(aliases.lib) : aliasToDir(aliases.components);
124
- const pathInDir = file.path.replace(/^(components|lib|ui|hooks)\//, "");
125
- return join(projectRoot, dir, pathInDir);
128
+ return join(projectRoot, resolveFileDestination(file.path, file.type, aliases, tsPaths));
126
129
  }
127
130
  function rewriteImports(content, aliases) {
128
131
  return content.replaceAll("@/lib/use-controllable-state", `${aliases.lib}/use-controllable-state`).replaceAll("@/lib/utils", aliases.utils);
@@ -138,6 +141,16 @@ function writeItem(item, aliases, written) {
138
141
  log(` ${GREEN}\u2713${RESET} ${basename(dest)}`);
139
142
  }
140
143
  }
144
+ async function ensureUtils(aliases, written, deps) {
145
+ const dest = join(
146
+ projectRoot,
147
+ resolveFileDestination("lib/utils.ts", "registry:lib", aliases, tsPaths)
148
+ );
149
+ if (written.has(dest) || existsSync(dest)) return;
150
+ const item = await fetchItem("utils");
151
+ for (const dep of item.dependencies ?? []) deps.add(dep);
152
+ writeItem(item, aliases, written);
153
+ }
141
154
  async function addComponents(names, aliases) {
142
155
  const visited = /* @__PURE__ */ new Set();
143
156
  const written = /* @__PURE__ */ new Set();
@@ -158,6 +171,7 @@ ${BOLD}${item.title ?? item.name}${RESET}`);
158
171
  for (const name of names) {
159
172
  await addItem(name);
160
173
  }
174
+ await ensureUtils(aliases, written, deps);
161
175
  if (deps.size > 0) {
162
176
  installDependencies(detectPackageManager(), [...deps]);
163
177
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/cli/index.ts","../../src/cli/paths.ts"],"sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { basename, dirname, join } from \"node:path\";\nimport { spawnSync } from \"node:child_process\";\nimport { parseJsonc, resolveAliasToDir, type TsPathsConfig } from \"./paths\";\n\nconst REGISTRY_URL = process.env.BABELIZE_REGISTRY ?? \"https://elements.babelize.co/r\";\nconst BASE_URL = REGISTRY_URL.replace(/\\/r\\/?$/, \"\");\n\nconst DEFAULT_ALIASES = {\n components: \"@/components\",\n ui: \"@/components/ui\",\n lib: \"@/lib\",\n utils: \"@/lib/utils\",\n hooks: \"@/hooks\",\n};\n\nconst GREEN = \"\\u001b[32m\";\nconst RED = \"\\u001b[31m\";\nconst CYAN = \"\\u001b[36m\";\nconst BOLD = \"\\u001b[1m\";\nconst RESET = \"\\u001b[0m\";\n\ninterface RegistryFile {\n path: string;\n type: string;\n content?: string;\n}\n\ninterface RegistryItem {\n $schema?: string;\n name: string;\n type: string;\n title?: string;\n description?: string;\n dependencies?: string[];\n registryDependencies?: string[];\n files?: RegistryFile[];\n}\n\nconst projectRoot = process.cwd();\n\nfunction log(message = \"\"): void {\n process.stdout.write(`${message}\\n`);\n}\n\nfunction error(message: string): void {\n process.stderr.write(`${RED}${message}${RESET}\\n`);\n}\n\nfunction readComponentsJson(): { aliases?: Record<string, string> } {\n try {\n return JSON.parse(readFileSync(join(projectRoot, \"components.json\"), \"utf8\"));\n } catch {\n return {};\n }\n}\n\nfunction readTsPaths(): TsPathsConfig | null {\n for (const file of [\"tsconfig.json\", \"jsconfig.json\"]) {\n let raw: string;\n try {\n raw = readFileSync(join(projectRoot, file), \"utf8\");\n } catch {\n continue;\n }\n const config = parseJsonc<{\n compilerOptions?: { baseUrl?: string; paths?: Record<string, string[]> };\n }>(raw);\n const options = config?.compilerOptions;\n if (options?.paths) {\n return { baseUrl: options.baseUrl ?? \".\", paths: options.paths };\n }\n }\n return null;\n}\n\nfunction resolveAliases(): Record<string, string> {\n const user = readComponentsJson().aliases ?? {};\n return { ...DEFAULT_ALIASES, ...user };\n}\n\nconst tsPaths = readTsPaths();\n\nfunction aliasToDir(alias: string): string {\n return resolveAliasToDir(alias, tsPaths);\n}\n\nasync function fetchItem(nameOrUrl: string): Promise<RegistryItem> {\n // registryDependencies are absolute URLs, because the shadcn CLI resolves bare\n // names against its own registry. Accept both forms.\n const url = /^https?:\\/\\//.test(nameOrUrl) ? nameOrUrl : `${REGISTRY_URL}/${nameOrUrl}.json`;\n const res = await fetch(url);\n if (!res.ok) {\n throw new Error(`Failed to fetch \"${nameOrUrl}\" from ${url} (HTTP ${res.status}).`);\n }\n return (await res.json()) as RegistryItem;\n}\n\nfunction detectPackageManager(): string {\n if (existsSync(join(projectRoot, \"bun.lock\")) || existsSync(join(projectRoot, \"bun.lockb\"))) {\n return \"bun\";\n }\n if (existsSync(join(projectRoot, \"pnpm-lock.yaml\"))) return \"pnpm\";\n if (existsSync(join(projectRoot, \"yarn.lock\"))) return \"yarn\";\n return \"npm\";\n}\n\nfunction installDependencies(pm: string, deps: string[]): void {\n const args = pm === \"npm\" ? [\"install\", ...deps] : [\"add\", ...deps];\n log(`\\n${CYAN}Installing dependencies with ${pm}${RESET}`);\n const result = spawnSync(pm, args, { cwd: projectRoot, stdio: \"inherit\" });\n if (result.status !== 0) process.exit(result.status ?? 1);\n}\n\nfunction resolveDestination(file: RegistryFile, aliases: Record<string, string>): string {\n const dir =\n file.type === \"registry:lib\" ? aliasToDir(aliases.lib) : aliasToDir(aliases.components);\n const pathInDir = file.path.replace(/^(components|lib|ui|hooks)\\//, \"\");\n return join(projectRoot, dir, pathInDir);\n}\n\nfunction rewriteImports(content: string, aliases: Record<string, string>): string {\n // Longest specifier first: \"@/lib/utils\" is a prefix of nothing here, but the\n // hook path must not be partially rewritten by a shorter rule later.\n return content\n .replaceAll(\"@/lib/use-controllable-state\", `${aliases.lib}/use-controllable-state`)\n .replaceAll(\"@/lib/utils\", aliases.utils);\n}\n\nfunction writeItem(\n item: RegistryItem,\n aliases: Record<string, string>,\n written: Set<string>,\n): void {\n for (const file of item.files ?? []) {\n if (!file.content) continue;\n const dest = resolveDestination(file, aliases);\n if (written.has(dest)) continue;\n mkdirSync(dirname(dest), { recursive: true });\n writeFileSync(dest, rewriteImports(file.content, aliases), \"utf8\");\n written.add(dest);\n log(` ${GREEN}✓${RESET} ${basename(dest)}`);\n }\n}\n\nasync function addComponents(names: string[], aliases: Record<string, string>): Promise<void> {\n const visited = new Set<string>();\n const written = new Set<string>();\n const deps = new Set<string>();\n\n async function addItem(name: string): Promise<void> {\n if (visited.has(name)) return;\n visited.add(name);\n\n const item = await fetchItem(name);\n log(`\\n${BOLD}${item.title ?? item.name}${RESET}`);\n if (item.description) log(` ${item.description}`);\n\n for (const dep of item.dependencies ?? []) deps.add(dep);\n writeItem(item, aliases, written);\n\n for (const dep of item.registryDependencies ?? []) {\n await addItem(dep);\n }\n }\n\n for (const name of names) {\n await addItem(name);\n }\n\n if (deps.size > 0) {\n installDependencies(detectPackageManager(), [...deps]);\n }\n\n log(`\\n${GREEN}${BOLD}Done.${RESET} Components written to ${aliases.components}.`);\n}\n\nasync function listComponents(): Promise<void> {\n const res = await fetch(`${BASE_URL}/registry.json`);\n if (!res.ok) {\n throw new Error(`Failed to fetch registry index (HTTP ${res.status}).`);\n }\n const index = (await res.json()) as { name: string; items: RegistryItem[] };\n log(`${BOLD}${index.name}${RESET} registry\\n`);\n for (const item of index.items) {\n const title = item.title ?? item.name;\n log(` ${CYAN}${item.name}${RESET} — ${item.description ?? title}`);\n }\n log(`\\nInstall a component:\\n npx shadcn@latest add @elements/<component>`);\n log(` npx @babelize/elements add <component>`);\n}\n\nfunction printUsage(): void {\n log(`${BOLD}Babelize Elements CLI${RESET}`);\n log(`\\nUsage:\\n babelize add <component...> Install components into your project`);\n log(` babelize list List available components\\n`);\n log(`Options:\\n --help Show this help\\n`);\n log(`Registry:\\n Set BABELIZE_REGISTRY to override the registry URL (default ${REGISTRY_URL}).`);\n}\n\nasync function main(): Promise<void> {\n const args = process.argv.slice(2);\n const command = args[0];\n\n if (command === \"--help\" || command === \"-h\" || !command) {\n printUsage();\n return;\n }\n\n const aliases = resolveAliases();\n\n try {\n if (command === \"add\") {\n const names = args.slice(1);\n if (names.length === 0) {\n error(\"No components specified. Usage: babelize add <component...>\");\n process.exit(1);\n }\n await addComponents(names, aliases);\n } else if (command === \"list\") {\n await listComponents();\n } else {\n error(`Unknown command: ${command}`);\n printUsage();\n process.exit(1);\n }\n } catch (err) {\n error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n}\n\nmain();\n","/**\n * Alias resolution for the `babelize add` CLI.\n *\n * components.json stores aliases as import specifiers (`@/components`), not\n * directories. Turning one into a path means consulting the consumer's tsconfig:\n * in most Next.js projects `@/*` maps to `./src/*`, so stripping the `@/` prefix\n * would write files a level too high and leave their imports unresolvable.\n */\n\nexport interface TsPathsConfig {\n baseUrl: string;\n paths: Record<string, string[]>;\n}\n\n/** Tolerates comments and trailing commas, which tsconfig.json is allowed to have. */\nexport function parseJsonc<T = unknown>(raw: string): T | null {\n try {\n const withoutComments = raw.replace(\n /\"(?:\\\\.|[^\"\\\\])*\"|\\/\\/[^\\n\\r]*|\\/\\*[\\s\\S]*?\\*\\//g,\n (match) => (match.startsWith('\"') ? match : \"\"),\n );\n return JSON.parse(withoutComments.replace(/,(\\s*[}\\]])/g, \"$1\")) as T;\n } catch {\n return null;\n }\n}\n\nfunction normalize(dir: string): string {\n return dir.replace(/^\\.\\//, \"\").replace(/\\/+$/, \"\");\n}\n\n/**\n * Resolves an alias such as `@/components/ui` to a directory relative to the\n * project root. Falls back to stripping a leading `@/` when there is no usable\n * tsconfig, which matches the pre-tsconfig behaviour.\n */\nexport function resolveAliasToDir(alias: string, config: TsPathsConfig | null): string {\n const fallback = normalize(alias.replace(/^@\\//, \"\"));\n if (!config) return fallback;\n\n const base = normalize(config.baseUrl || \".\");\n const joinParts = (...parts: string[]) => parts.filter(Boolean).join(\"/\");\n const prefixed = (rest: string) => normalize(joinParts(base, rest));\n\n // Longest pattern first, so `@/lib/*` beats `@/*` when both are declared.\n const entries = Object.entries(config.paths).sort((a, b) => b[0].length - a[0].length);\n\n for (const [pattern, targets] of entries) {\n const target = targets[0];\n if (!target) continue;\n\n if (pattern.endsWith(\"/*\") && target.endsWith(\"/*\")) {\n const aliasPrefix = pattern.slice(0, -1);\n if (alias === aliasPrefix.slice(0, -1) || alias.startsWith(aliasPrefix)) {\n const rest = alias.slice(aliasPrefix.length);\n return prefixed(joinParts(normalize(target.slice(0, -1)), rest));\n }\n } else if (pattern === alias) {\n return prefixed(normalize(target));\n }\n }\n\n return fallback;\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/cli/index.ts","../../src/cli/paths.ts"],"sourcesContent":["import { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { basename, dirname, join } from \"node:path\";\nimport { spawnSync } from \"node:child_process\";\nimport { parseJsonc, resolveFileDestination, type TsPathsConfig } from \"./paths\";\n\nconst REGISTRY_URL = process.env.BABELIZE_REGISTRY ?? \"https://elements.babelize.co/r\";\nconst BASE_URL = REGISTRY_URL.replace(/\\/r\\/?$/, \"\");\n\nconst DEFAULT_ALIASES = {\n components: \"@/components\",\n ui: \"@/components/ui\",\n lib: \"@/lib\",\n utils: \"@/lib/utils\",\n hooks: \"@/hooks\",\n};\n\nconst GREEN = \"\\u001b[32m\";\nconst RED = \"\\u001b[31m\";\nconst CYAN = \"\\u001b[36m\";\nconst BOLD = \"\\u001b[1m\";\nconst RESET = \"\\u001b[0m\";\n\ninterface RegistryFile {\n path: string;\n type: string;\n content?: string;\n}\n\ninterface RegistryItem {\n $schema?: string;\n name: string;\n type: string;\n title?: string;\n description?: string;\n dependencies?: string[];\n registryDependencies?: string[];\n files?: RegistryFile[];\n}\n\nconst projectRoot = process.cwd();\n\nfunction log(message = \"\"): void {\n process.stdout.write(`${message}\\n`);\n}\n\nfunction error(message: string): void {\n process.stderr.write(`${RED}${message}${RESET}\\n`);\n}\n\nfunction readComponentsJson(): { aliases?: Record<string, string> } {\n try {\n return JSON.parse(readFileSync(join(projectRoot, \"components.json\"), \"utf8\"));\n } catch {\n return {};\n }\n}\n\nfunction readTsPaths(): TsPathsConfig | null {\n for (const file of [\"tsconfig.json\", \"jsconfig.json\"]) {\n let raw: string;\n try {\n raw = readFileSync(join(projectRoot, file), \"utf8\");\n } catch {\n continue;\n }\n const config = parseJsonc<{\n compilerOptions?: { baseUrl?: string; paths?: Record<string, string[]> };\n }>(raw);\n const options = config?.compilerOptions;\n if (options?.paths) {\n return { baseUrl: options.baseUrl ?? \".\", paths: options.paths };\n }\n }\n return null;\n}\n\nfunction resolveAliases(): Record<string, string> {\n const user = readComponentsJson().aliases ?? {};\n return { ...DEFAULT_ALIASES, ...user };\n}\n\nconst tsPaths = readTsPaths();\n\nasync function fetchItem(nameOrUrl: string): Promise<RegistryItem> {\n // registryDependencies are absolute URLs, because the shadcn CLI resolves bare\n // names against its own registry. Accept both forms.\n const url = /^https?:\\/\\//.test(nameOrUrl) ? nameOrUrl : `${REGISTRY_URL}/${nameOrUrl}.json`;\n const res = await fetch(url);\n if (!res.ok) {\n throw new Error(`Failed to fetch \"${nameOrUrl}\" from ${url} (HTTP ${res.status}).`);\n }\n return (await res.json()) as RegistryItem;\n}\n\nfunction detectPackageManager(): string {\n if (existsSync(join(projectRoot, \"bun.lock\")) || existsSync(join(projectRoot, \"bun.lockb\"))) {\n return \"bun\";\n }\n if (existsSync(join(projectRoot, \"pnpm-lock.yaml\"))) return \"pnpm\";\n if (existsSync(join(projectRoot, \"yarn.lock\"))) return \"yarn\";\n return \"npm\";\n}\n\nfunction installDependencies(pm: string, deps: string[]): void {\n const args = pm === \"npm\" ? [\"install\", ...deps] : [\"add\", ...deps];\n log(`\\n${CYAN}Installing dependencies with ${pm}${RESET}`);\n const result = spawnSync(pm, args, { cwd: projectRoot, stdio: \"inherit\" });\n if (result.status !== 0) process.exit(result.status ?? 1);\n}\n\nfunction resolveDestination(file: RegistryFile, aliases: Record<string, string>): string {\n return join(projectRoot, resolveFileDestination(file.path, file.type, aliases, tsPaths));\n}\n\nfunction rewriteImports(content: string, aliases: Record<string, string>): string {\n // Longest specifier first: \"@/lib/utils\" is a prefix of nothing here, but the\n // hook path must not be partially rewritten by a shorter rule later.\n return content\n .replaceAll(\"@/lib/use-controllable-state\", `${aliases.lib}/use-controllable-state`)\n .replaceAll(\"@/lib/utils\", aliases.utils);\n}\n\nfunction writeItem(\n item: RegistryItem,\n aliases: Record<string, string>,\n written: Set<string>,\n): void {\n for (const file of item.files ?? []) {\n if (!file.content) continue;\n const dest = resolveDestination(file, aliases);\n if (written.has(dest)) continue;\n mkdirSync(dirname(dest), { recursive: true });\n writeFileSync(dest, rewriteImports(file.content, aliases), \"utf8\");\n written.add(dest);\n log(` ${GREEN}✓${RESET} ${basename(dest)}`);\n }\n}\n\n/**\n * Writes `cn` only when the project does not already have it.\n *\n * The registry does not list `utils` as a dependency of any component — shadcn's\n * own components assume `cn` exists, because `shadcn init` creates it. This CLI\n * also runs in projects that never ran `shadcn init`, so it fills the gap here,\n * and skips the file when it is already present rather than overwriting a `cn`\n * the project may have customised.\n */\nasync function ensureUtils(\n aliases: Record<string, string>,\n written: Set<string>,\n deps: Set<string>,\n): Promise<void> {\n const dest = join(\n projectRoot,\n resolveFileDestination(\"lib/utils.ts\", \"registry:lib\", aliases, tsPaths),\n );\n if (written.has(dest) || existsSync(dest)) return;\n\n const item = await fetchItem(\"utils\");\n for (const dep of item.dependencies ?? []) deps.add(dep);\n writeItem(item, aliases, written);\n}\n\nasync function addComponents(names: string[], aliases: Record<string, string>): Promise<void> {\n const visited = new Set<string>();\n const written = new Set<string>();\n const deps = new Set<string>();\n\n async function addItem(name: string): Promise<void> {\n if (visited.has(name)) return;\n visited.add(name);\n\n const item = await fetchItem(name);\n log(`\\n${BOLD}${item.title ?? item.name}${RESET}`);\n if (item.description) log(` ${item.description}`);\n\n for (const dep of item.dependencies ?? []) deps.add(dep);\n writeItem(item, aliases, written);\n\n for (const dep of item.registryDependencies ?? []) {\n await addItem(dep);\n }\n }\n\n for (const name of names) {\n await addItem(name);\n }\n\n await ensureUtils(aliases, written, deps);\n\n if (deps.size > 0) {\n installDependencies(detectPackageManager(), [...deps]);\n }\n\n log(`\\n${GREEN}${BOLD}Done.${RESET} Components written to ${aliases.components}.`);\n}\n\nasync function listComponents(): Promise<void> {\n const res = await fetch(`${BASE_URL}/registry.json`);\n if (!res.ok) {\n throw new Error(`Failed to fetch registry index (HTTP ${res.status}).`);\n }\n const index = (await res.json()) as { name: string; items: RegistryItem[] };\n log(`${BOLD}${index.name}${RESET} registry\\n`);\n for (const item of index.items) {\n const title = item.title ?? item.name;\n log(` ${CYAN}${item.name}${RESET} — ${item.description ?? title}`);\n }\n log(`\\nInstall a component:\\n npx shadcn@latest add @elements/<component>`);\n log(` npx @babelize/elements add <component>`);\n}\n\nfunction printUsage(): void {\n log(`${BOLD}Babelize Elements CLI${RESET}`);\n log(`\\nUsage:\\n babelize add <component...> Install components into your project`);\n log(` babelize list List available components\\n`);\n log(`Options:\\n --help Show this help\\n`);\n log(`Registry:\\n Set BABELIZE_REGISTRY to override the registry URL (default ${REGISTRY_URL}).`);\n}\n\nasync function main(): Promise<void> {\n const args = process.argv.slice(2);\n const command = args[0];\n\n if (command === \"--help\" || command === \"-h\" || !command) {\n printUsage();\n return;\n }\n\n const aliases = resolveAliases();\n\n try {\n if (command === \"add\") {\n const names = args.slice(1);\n if (names.length === 0) {\n error(\"No components specified. Usage: babelize add <component...>\");\n process.exit(1);\n }\n await addComponents(names, aliases);\n } else if (command === \"list\") {\n await listComponents();\n } else {\n error(`Unknown command: ${command}`);\n printUsage();\n process.exit(1);\n }\n } catch (err) {\n error(err instanceof Error ? err.message : String(err));\n process.exit(1);\n }\n}\n\nmain();\n","/**\n * Alias resolution for the `babelize add` CLI.\n *\n * components.json stores aliases as import specifiers (`@/components`), not\n * directories. Turning one into a path means consulting the consumer's tsconfig:\n * in most Next.js projects `@/*` maps to `./src/*`, so stripping the `@/` prefix\n * would write files a level too high and leave their imports unresolvable.\n */\n\nexport interface TsPathsConfig {\n baseUrl: string;\n paths: Record<string, string[]>;\n}\n\n/** Tolerates comments and trailing commas, which tsconfig.json is allowed to have. */\nexport function parseJsonc<T = unknown>(raw: string): T | null {\n try {\n const withoutComments = raw.replace(\n /\"(?:\\\\.|[^\"\\\\])*\"|\\/\\/[^\\n\\r]*|\\/\\*[\\s\\S]*?\\*\\//g,\n (match) => (match.startsWith('\"') ? match : \"\"),\n );\n return JSON.parse(withoutComments.replace(/,(\\s*[}\\]])/g, \"$1\")) as T;\n } catch {\n return null;\n }\n}\n\nfunction normalize(dir: string): string {\n return dir.replace(/^\\.\\//, \"\").replace(/\\/+$/, \"\");\n}\n\n/**\n * Resolves an alias such as `@/components/ui` to a directory relative to the\n * project root. Falls back to stripping a leading `@/` when there is no usable\n * tsconfig, which matches the pre-tsconfig behaviour.\n */\nexport function resolveAliasToDir(alias: string, config: TsPathsConfig | null): string {\n const fallback = normalize(alias.replace(/^@\\//, \"\"));\n if (!config) return fallback;\n\n const base = normalize(config.baseUrl || \".\");\n const joinParts = (...parts: string[]) => parts.filter(Boolean).join(\"/\");\n const prefixed = (rest: string) => normalize(joinParts(base, rest));\n\n // Longest pattern first, so `@/lib/*` beats `@/*` when both are declared.\n const entries = Object.entries(config.paths).sort((a, b) => b[0].length - a[0].length);\n\n for (const [pattern, targets] of entries) {\n const target = targets[0];\n if (!target) continue;\n\n if (pattern.endsWith(\"/*\") && target.endsWith(\"/*\")) {\n const aliasPrefix = pattern.slice(0, -1);\n if (alias === aliasPrefix.slice(0, -1) || alias.startsWith(aliasPrefix)) {\n const rest = alias.slice(aliasPrefix.length);\n return prefixed(joinParts(normalize(target.slice(0, -1)), rest));\n }\n } else if (pattern === alias) {\n return prefixed(normalize(target));\n }\n }\n\n return fallback;\n}\n\n/**\n * Path a registry file is written to, relative to the project root.\n *\n * Each registry type selects the alias it is written under — `ui`, `lib`, `hooks`\n * — matching how the shadcn CLI resolves the same item.\n *\n * `cn` is the exception: its location is pinned by an alias other than the\n * directory it nominally lives in, because components import it through `utils`,\n * which a project may point somewhere other than `<lib>/utils`. Writing it under\n * `lib` in that case leaves every component importing a file that does not exist.\n */\nexport function resolveFileDestination(\n filePath: string,\n fileType: string,\n aliases: Record<string, string>,\n config: TsPathsConfig | null,\n): string {\n const toDir = (alias: string) => resolveAliasToDir(alias, config);\n\n if (filePath.replace(/^lib\\//, \"\") === \"utils.ts\") {\n return `${toDir(aliases.utils)}.ts`;\n }\n\n const dir =\n fileType === \"registry:lib\"\n ? toDir(aliases.lib)\n : fileType === \"registry:hook\"\n ? toDir(aliases.hooks)\n : fileType === \"registry:ui\"\n ? toDir(aliases.ui)\n : toDir(aliases.components);\n\n return [dir, filePath.replace(/^(components|lib|ui|hooks)\\//, \"\")].filter(Boolean).join(\"/\");\n}\n"],"mappings":"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","names":[]}