@beaket/ui 0.1.8 → 1.0.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@beaket/ui",
3
- "version": "0.1.8",
3
+ "version": "1.0.0",
4
4
  "description": "CLI tool for adding Beaket UI components to your project",
5
5
  "type": "module",
6
6
  "bin": {
@@ -4,7 +4,11 @@ import { getConfig } from "../utils/config.ts";
4
4
  import { installDependencies, writeComponentFiles } from "../utils/files.ts";
5
5
  import { fetchComponent, fetchRegistry } from "../utils/registry.ts";
6
6
 
7
- export async function add(componentName: string) {
7
+ interface AddOptions {
8
+ overwrite?: boolean;
9
+ }
10
+
11
+ export async function add(componentName: string, options: AddOptions) {
8
12
  console.log();
9
13
 
10
14
  // Read config
@@ -16,9 +20,9 @@ export async function add(componentName: string) {
16
20
  }
17
21
 
18
22
  // Fetch registry
19
- console.log(`Adding ${pc.cyan(componentName)}...`);
20
-
21
23
  const registry = await fetchRegistry();
24
+ console.log(pc.green("✔"), "Checking registry.");
25
+
22
26
  const componentDef = registry.components.find((c) => c.name === componentName);
23
27
 
24
28
  if (!componentDef) {
@@ -31,35 +35,35 @@ export async function add(componentName: string) {
31
35
  process.exit(1);
32
36
  }
33
37
 
38
+ // Install dependencies
39
+ if (componentDef.dependencies.length > 0) {
40
+ await installDependencies(componentDef.dependencies);
41
+ console.log(pc.green("✔"), "Installing dependencies.");
42
+ }
43
+
34
44
  // Fetch component files
35
45
  const files = await fetchComponent(componentDef);
36
46
 
37
47
  // Write files
38
- const componentsDir = path.join(process.cwd(), config.paths.components);
39
- await writeComponentFiles(componentsDir, componentName, files, config);
48
+ const componentsDir = path.join(process.cwd(), config.components);
49
+ const { written, skipped } = await writeComponentFiles(componentsDir, files, options.overwrite);
40
50
 
41
- console.log(pc.green("✓"), `Added ${componentName}`);
51
+ // Show skipped files
52
+ if (skipped.length > 0) {
53
+ console.log(
54
+ pc.yellow("ℹ"),
55
+ `Skipped ${skipped.length} file(s): (use --overwrite to overwrite)`,
56
+ );
57
+ skipped.forEach((f) => console.log(` - ${f}`));
58
+ }
42
59
 
43
- // Install dependencies
44
- if (componentDef.dependencies.length > 0) {
60
+ if (written.length === 0) {
45
61
  console.log();
46
- console.log("Installing dependencies...");
47
- await installDependencies(componentDef.dependencies);
48
- console.log(pc.green("✓"), `Installed ${componentDef.dependencies.join(", ")}`);
62
+ return;
49
63
  }
64
+
50
65
  console.log();
51
- console.log("Import it in your code:");
52
- console.log(
53
- pc.cyan(
54
- ` import { ${pascalCase(componentName)} } from "${config.aliases.components}/${componentName}";`,
55
- ),
56
- );
66
+ console.log("Added:");
67
+ written.forEach((f) => console.log(pc.cyan(` ${f}`)));
57
68
  console.log();
58
69
  }
59
-
60
- function pascalCase(str: string): string {
61
- return str
62
- .split("-")
63
- .map((word) => word.charAt(0).toUpperCase() + word.slice(1))
64
- .join("");
65
- }
@@ -3,7 +3,6 @@ import path from "path";
3
3
  import pc from "picocolors";
4
4
  import prompts from "prompts";
5
5
  import { writeConfig, type BeaketConfig } from "../utils/config.ts";
6
- import { installDependencies } from "../utils/files.ts";
7
6
 
8
7
  const CSS_VARIABLES = `
9
8
  /* Beaket UI Design System */
@@ -38,97 +37,54 @@ export async function init() {
38
37
  const response = await prompts([
39
38
  {
40
39
  type: "text",
41
- name: "componentsDir",
42
- message: "Where would you like to install components?",
43
- initial: "src/components",
40
+ name: "components",
41
+ message: "Where should components be installed?",
42
+ initial: "src/components/ui",
44
43
  },
45
44
  {
46
45
  type: "text",
47
- name: "utilsDir",
48
- message: "Where would you like to install utilities (cn, etc.)?",
49
- initial: "src/lib",
50
- },
51
- {
52
- type: "text",
53
- name: "tailwindCss",
46
+ name: "css",
54
47
  message: "Where is your Tailwind CSS file?",
55
48
  initial: "src/index.css",
56
49
  },
57
- {
58
- type: "text",
59
- name: "componentsAlias",
60
- message: "Components import alias",
61
- initial: "@/components",
62
- },
63
- {
64
- type: "text",
65
- name: "utilsAlias",
66
- message: "Utils import alias",
67
- initial: "@/lib",
68
- },
69
50
  ]);
70
51
 
71
- if (!response.componentsDir) {
52
+ if (!response.components) {
72
53
  console.log(pc.red("Cancelled."));
73
54
  process.exit(1);
74
55
  }
75
56
 
57
+ // Write beaket.json (only components path)
76
58
  const config: BeaketConfig = {
77
59
  $schema: "https://beaket.dev/schema.json",
78
- tailwind: {
79
- css: response.tailwindCss,
80
- },
81
- aliases: {
82
- components: response.componentsAlias,
83
- utils: response.utilsAlias,
84
- },
85
- paths: {
86
- components: response.componentsDir,
87
- utils: response.utilsDir,
88
- },
60
+ components: response.components,
89
61
  };
90
62
 
91
- // Write beaket.json
92
63
  await writeConfig(config);
93
- console.log(pc.green(""), "Created beaket.json");
64
+ console.log(pc.green(""), "Created beaket.json");
94
65
 
95
66
  // Inject CSS variables into Tailwind CSS file
96
- const cssPath = path.join(process.cwd(), response.tailwindCss);
97
- if (await fs.pathExists(cssPath)) {
98
- const cssContent = await fs.readFile(cssPath, "utf-8");
99
- if (!cssContent.includes("Beaket UI Design System")) {
100
- await fs.writeFile(cssPath, cssContent + CSS_VARIABLES);
101
- console.log(pc.green("✓"), `Added CSS variables to ${response.tailwindCss}`);
67
+ if (response.css) {
68
+ const cssPath = path.join(process.cwd(), response.css);
69
+ if (await fs.pathExists(cssPath)) {
70
+ const cssContent = await fs.readFile(cssPath, "utf-8");
71
+ if (!cssContent.includes("Beaket UI Design System")) {
72
+ await fs.writeFile(cssPath, cssContent + CSS_VARIABLES);
73
+ console.log(pc.green("✔"), `Added CSS variables to ${response.css}`);
74
+ } else {
75
+ console.log(pc.yellow("ℹ"), "CSS variables already exist");
76
+ }
77
+ } else {
78
+ console.log(pc.yellow("!"), `CSS file not found: ${response.css}`);
79
+ console.log(" Add CSS variables manually:");
80
+ console.log(pc.cyan(" https://beaket.github.io/ui/installation"));
102
81
  }
103
- } else {
104
- console.log(pc.yellow("!"), `CSS file not found: ${response.tailwindCss}`);
105
82
  }
106
83
 
107
- // Create utils directory and cn function
108
- const utilsDir = path.join(process.cwd(), response.utilsDir);
109
- await fs.ensureDir(utilsDir);
110
-
111
- const cnContent = `import { type ClassValue, clsx } from "clsx";
112
- import { twMerge } from "tailwind-merge";
113
-
114
- export function cn(...inputs: ClassValue[]) {
115
- return twMerge(clsx(inputs));
116
- }
117
- `;
118
-
119
- await fs.writeFile(path.join(utilsDir, "utils.ts"), cnContent);
120
- console.log(pc.green("✓"), `Created ${response.utilsDir}/utils.ts`);
121
-
122
- // Install dependencies
123
- console.log();
124
- console.log("Installing dependencies...");
125
- await installDependencies(["clsx", "tailwind-merge"]);
126
- console.log(pc.green("✓"), "Installed clsx, tailwind-merge");
127
-
128
84
  console.log();
129
85
  console.log(pc.green("Done!"), "Beaket UI is ready.");
130
86
  console.log();
131
- console.log("You can now add components:");
87
+ console.log("Add components:");
132
88
  console.log(pc.cyan(" npx @beaket/ui add button"));
133
89
  console.log();
134
90
  }
package/src/index.ts CHANGED
@@ -21,6 +21,7 @@ program
21
21
  .command("add")
22
22
  .description("Add a component to your project")
23
23
  .argument("<component>", "Component name to add")
24
+ .option("-o, --overwrite", "Overwrite existing files")
24
25
  .action(add);
25
26
 
26
27
  program.parse();
@@ -3,17 +3,7 @@ import path from "path";
3
3
 
4
4
  export interface BeaketConfig {
5
5
  $schema?: string;
6
- tailwind: {
7
- css: string;
8
- };
9
- aliases: {
10
- components: string;
11
- utils: string;
12
- };
13
- paths: {
14
- components: string;
15
- utils: string;
16
- };
6
+ components: string;
17
7
  }
18
8
 
19
9
  const CONFIG_FILE = "beaket.json";
@@ -1,32 +1,49 @@
1
1
  import { spawn } from "child_process";
2
2
  import fs from "fs-extra";
3
3
  import path from "path";
4
- import type { BeaketConfig } from "./config.ts";
4
+ import prompts from "prompts";
5
5
  import type { ComponentFile } from "./registry.ts";
6
6
 
7
+ export interface WriteResult {
8
+ written: string[];
9
+ skipped: string[];
10
+ }
11
+
7
12
  export async function writeComponentFiles(
8
13
  baseDir: string,
9
- componentName: string,
10
14
  files: ComponentFile[],
11
- config: BeaketConfig,
12
- ): Promise<void> {
15
+ overwrite: boolean = false,
16
+ ): Promise<WriteResult> {
17
+ const written: string[] = [];
18
+ const skipped: string[] = [];
19
+
13
20
  for (const file of files) {
14
- // Transform file path: components/button/button.tsx -> button/button.tsx
21
+ // Transform file path: components/button.tsx -> button.tsx
15
22
  const relativePath = file.path.replace(/^components\//, "");
16
23
  const targetPath = path.join(baseDir, relativePath);
17
24
 
18
- // Transform imports in content
19
- let content = file.content;
20
-
21
- // Replace @/lib/utils with user's utils alias
22
- content = content.replace(/@\/lib\/utils/g, `${config.aliases.utils}/utils`);
23
-
24
- // Replace @/components with user's components alias
25
- content = content.replace(/@\/components/g, config.aliases.components);
25
+ // Check if file exists
26
+ if (await fs.pathExists(targetPath)) {
27
+ if (!overwrite) {
28
+ const { confirm } = await prompts({
29
+ type: "confirm",
30
+ name: "confirm",
31
+ message: `${path.basename(targetPath)} already exists. Overwrite?`,
32
+ initial: false,
33
+ });
34
+ if (!confirm) {
35
+ skipped.push(targetPath);
36
+ continue;
37
+ }
38
+ }
39
+ }
26
40
 
27
41
  await fs.ensureDir(path.dirname(targetPath));
28
- await fs.writeFile(targetPath, content);
42
+ await fs.writeFile(targetPath, file.content);
43
+ written.push(targetPath);
29
44
  }
45
+
46
+ return { written, skipped };
30
47
  }
31
48
 
32
49
  export async function installDependencies(deps: string[]): Promise<void> {