@dinachi/cli 0.2.1 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -411,7 +411,30 @@ ${pluginsContent},
411
411
  }
412
412
  return { exists: true };
413
413
  }
414
- var addCommand = new Command("add").description("Add a component to your project").argument("<component>", "Name of the component").option("-y, --yes", "Skip confirmation prompts").option("-o, --overwrite", "Overwrite existing files").action(async (componentName, options) => {
414
+ async function handleIndexFile(sourcePath, targetPath, componentName, allFilesAdded, aliasPath) {
415
+ let templateContent = await fs2.readFile(sourcePath, "utf-8");
416
+ templateContent = templateContent.replace(/^\/\/ @ts-nocheck\s*\n/m, "");
417
+ if (!fs2.existsSync(targetPath)) {
418
+ await fs2.writeFile(targetPath, templateContent);
419
+ allFilesAdded.push({ name: "index.ts", path: path2.join(aliasPath, "index.ts") });
420
+ } else {
421
+ const existingContent = await fs2.readFile(targetPath, "utf-8");
422
+ const exportRegex = /export\s+\*\s+from\s+['"]\.\/([^'"]+)['"]/g;
423
+ const templateExports = [];
424
+ let match;
425
+ while ((match = exportRegex.exec(templateContent)) !== null) {
426
+ templateExports.push(match[1]);
427
+ }
428
+ const componentExportExists = existingContent.includes(`export * from './${componentName}'`);
429
+ if (!componentExportExists && templateExports.includes(componentName)) {
430
+ const newExportLine = `export * from './${componentName}'`;
431
+ const updatedContent = existingContent.trim() + "\n" + newExportLine + "\n";
432
+ await fs2.writeFile(targetPath, updatedContent);
433
+ allFilesAdded.push({ name: "index.ts", path: path2.join(aliasPath, "index.ts") });
434
+ }
435
+ }
436
+ }
437
+ var addCommand = new Command("add").description("Add a component to your project").argument("[component]", "Name of the component (optional when using --all)").option("-y, --yes", "Skip confirmation prompts").option("-o, --overwrite", "Overwrite existing files").option("-a, --all", "Install all available components").action(async (componentName, options) => {
415
438
  const spinner = ora("Adding component...").start();
416
439
  try {
417
440
  const config = await getConfig();
@@ -420,17 +443,40 @@ var addCommand = new Command("add").description("Add a component to your project
420
443
  process.exit(1);
421
444
  }
422
445
  const registry = getComponentRegistry();
423
- const component = registry[componentName];
424
- if (!component) {
425
- spinner.fail(`\u274C Component "${componentName}" not found.`);
426
- console.log("Available components:");
427
- Object.keys(registry).forEach((name) => {
428
- console.log(` ${chalk.cyan(name)}`);
429
- });
430
- process.exit(1);
446
+ let componentsToInstall = [];
447
+ if (options.all) {
448
+ const allComponents = Object.keys(registry);
449
+ spinner.text = `Installing all ${allComponents.length} components...`;
450
+ const allComponentsWithDeps = /* @__PURE__ */ new Set();
451
+ for (const name of allComponents) {
452
+ allComponentsWithDeps.add(name);
453
+ const deps = getComponentDependencies(name);
454
+ deps.forEach((dep) => allComponentsWithDeps.add(dep));
455
+ }
456
+ componentsToInstall = Array.from(allComponentsWithDeps);
457
+ } else {
458
+ if (!componentName) {
459
+ spinner.fail("\u274C Component name is required when not using --all flag.");
460
+ console.log("Available components:");
461
+ Object.keys(registry).forEach((name) => {
462
+ console.log(` ${chalk.cyan(name)}`);
463
+ });
464
+ process.exit(1);
465
+ }
466
+ const component = registry[componentName];
467
+ if (!component) {
468
+ spinner.fail(`\u274C Component "${componentName}" not found.`);
469
+ console.log("Available components:");
470
+ Object.keys(registry).forEach((name) => {
471
+ console.log(` ${chalk.cyan(name)}`);
472
+ });
473
+ process.exit(1);
474
+ }
475
+ componentsToInstall = [componentName, ...getComponentDependencies(componentName)];
476
+ }
477
+ if (!options.all) {
478
+ spinner.text = `Installing ${componentsToInstall.join(", ")}...`;
431
479
  }
432
- const componentsToInstall = [componentName, ...getComponentDependencies(componentName)];
433
- spinner.text = `Installing ${componentsToInstall.join(", ")}...`;
434
480
  const componentDir = path2.join(process.cwd(), config.aliases.ui.replace("@/", "src/"));
435
481
  await fs2.ensureDir(componentDir);
436
482
  let allFilesAdded = [];
@@ -474,14 +520,18 @@ var addCommand = new Command("add").description("Add a component to your project
474
520
  for (const file of comp.files) {
475
521
  const sourcePath = path2.join(__dirname2, "../templates", name, file.name);
476
522
  const targetPath = path2.join(componentDir, file.name);
477
- if (fs2.existsSync(targetPath) && !options.overwrite) {
478
- spinner.warn(`\u26A0\uFE0F ${file.name} already exists. Use --overwrite to replace it.`);
479
- continue;
523
+ if (file.name === "index.ts") {
524
+ await handleIndexFile(sourcePath, targetPath, name, allFilesAdded, config.aliases.ui);
525
+ } else {
526
+ if (fs2.existsSync(targetPath) && !options.overwrite) {
527
+ spinner.warn(`\u26A0\uFE0F ${file.name} already exists. Use --overwrite to replace it.`);
528
+ continue;
529
+ }
530
+ let content = await fs2.readFile(sourcePath, "utf-8");
531
+ content = content.replace(/^\/\/ @ts-nocheck\s*\n/m, "");
532
+ await fs2.writeFile(targetPath, content);
533
+ allFilesAdded.push({ name: file.name, path: path2.join(config.aliases.ui, file.name) });
480
534
  }
481
- let content = await fs2.readFile(sourcePath, "utf-8");
482
- content = content.replace(/^\/\/ @ts-nocheck\s*\n/m, "");
483
- await fs2.writeFile(targetPath, content);
484
- allFilesAdded.push({ name: file.name, path: path2.join(config.aliases.ui, file.name) });
485
535
  }
486
536
  if (comp.dependencies?.length) {
487
537
  allDepsInstalled.push(...comp.dependencies);
@@ -492,12 +542,12 @@ var addCommand = new Command("add").description("Add a component to your project
492
542
  spinner.text = "Updating Tailwind configuration...";
493
543
  tailwindConfigInfo = await ensureTailwindConfig(allDepsInstalled);
494
544
  }
545
+ const packageJsonPath = path2.join(process.cwd(), "package.json");
546
+ const packageJson = JSON.parse(await fs2.readFile(packageJsonPath, "utf-8"));
547
+ const allDeps = { ...packageJson.dependencies, ...packageJson.devDependencies };
548
+ const missingDeps = [...new Set(allDepsInstalled)].filter((dep) => !allDeps[dep]);
495
549
  if (allDepsInstalled.length > 0) {
496
550
  spinner.text = "Installing dependencies...";
497
- const packageJsonPath = path2.join(process.cwd(), "package.json");
498
- const packageJson = JSON.parse(await fs2.readFile(packageJsonPath, "utf-8"));
499
- const allDeps = { ...packageJson.dependencies, ...packageJson.devDependencies };
500
- const missingDeps = [...new Set(allDepsInstalled)].filter((dep) => !allDeps[dep]);
501
551
  if (missingDeps.length > 0) {
502
552
  try {
503
553
  const packageManager = getPackageManager();
@@ -506,9 +556,15 @@ var addCommand = new Command("add").description("Add a component to your project
506
556
  } catch (error) {
507
557
  spinner.warn(`\u26A0\uFE0F Failed to install dependencies. Please install manually: ${missingDeps.join(" ")}`);
508
558
  }
559
+ } else {
560
+ spinner.text = "All dependencies already installed.";
509
561
  }
510
562
  }
511
- spinner.succeed(`\u2705 Added ${componentsToInstall.join(", ")} component(s)!`);
563
+ if (options.all) {
564
+ spinner.succeed(`\u2705 Added all ${componentsToInstall.length} components!`);
565
+ } else {
566
+ spinner.succeed(`\u2705 Added ${componentsToInstall.join(", ")} component(s)!`);
567
+ }
512
568
  console.log();
513
569
  console.log("Files added:");
514
570
  allFilesAdded.forEach((file) => {
@@ -522,12 +578,18 @@ var addCommand = new Command("add").description("Add a component to your project
522
578
  console.log(` ${chalk.blue("~")} tailwind.config.js (updated with tailwindcss-animate plugin)`);
523
579
  }
524
580
  }
525
- if (allDepsInstalled.length > 0) {
581
+ if (missingDeps.length > 0) {
526
582
  console.log();
527
583
  console.log("Dependencies installed:");
528
- [...new Set(allDepsInstalled)].forEach((dep) => {
584
+ missingDeps.forEach((dep) => {
529
585
  console.log(` ${chalk.green("\u2713")} ${dep}`);
530
586
  });
587
+ } else if (allDepsInstalled.length > 0) {
588
+ console.log();
589
+ console.log("Dependencies (already installed):");
590
+ [...new Set(allDepsInstalled)].forEach((dep) => {
591
+ console.log(` ${chalk.blue("~")} ${dep}`);
592
+ });
531
593
  }
532
594
  } catch (error) {
533
595
  spinner.fail(`\u274C Failed to add component: ${error instanceof Error ? error.message : error}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dinachi/cli",
3
- "version": "0.2.1",
3
+ "version": "0.3.0",
4
4
  "description": "CLI for adding Dinachi UI components to your project",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -4,7 +4,7 @@ import { cva, type VariantProps } from "class-variance-authority"
4
4
  import { cn } from "@/lib/utils"
5
5
 
6
6
  const buttonVariants = cva(
7
- "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
7
+ "inline-flex items-center cursor-pointer justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50",
8
8
  {
9
9
  variants: {
10
10
  variant: {
@@ -12,7 +12,7 @@ const DialogTrigger = React.forwardRef<
12
12
  <BaseDialog.Trigger
13
13
  ref={ref}
14
14
  className={cn(
15
- "inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors",
15
+ "inline-flex items-center cursor-pointer justify-center whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors",
16
16
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
17
17
  "disabled:pointer-events-none disabled:opacity-50",
18
18
  "bg-primary text-primary-foreground hover:bg-primary/90",
@@ -23,7 +23,7 @@ const SelectTrigger = React.forwardRef<
23
23
  <SelectPrimitive.Trigger
24
24
  ref={ref}
25
25
  className={cn(
26
- "flex h-10 w-full items-center justify-between rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
26
+ "flex h-10 w-full items-center cursor-pointer justify-between rounded-md border border-input bg-transparent px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
27
27
  className
28
28
  )}
29
29
  {...props}