beste-cli 0.1.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.
Files changed (3) hide show
  1. package/README.md +77 -0
  2. package/bin/index.js +141 -0
  3. package/package.json +49 -0
package/README.md ADDED
@@ -0,0 +1,77 @@
1
+ # beste-cli
2
+
3
+ Official CLI for [beste.co](https://ui.beste.co) - Install premium shadcn components with a single command.
4
+
5
+ [![npm version](https://img.shields.io/npm/v/beste-cli.svg)](https://www.npmjs.com/package/beste-cli)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+
8
+ ## 🚀 Installation
9
+
10
+ Install globally to use `beste` command anywhere:
11
+
12
+ ```bash
13
+ npm install -g beste-cli
14
+ ```
15
+
16
+ Or use with `npx` without installation:
17
+
18
+ ```bash
19
+ npx beste-cli add https://ui.beste.co/r/feature63
20
+ ```
21
+
22
+ ## 📦 Usage
23
+
24
+ ### Add a Component
25
+
26
+ ```bash
27
+ beste add https://ui.beste.co/r/feature63
28
+ ```
29
+
30
+ The CLI will:
31
+
32
+ - ✅ Fetch the component from beste.co
33
+ - ✅ Detect your project structure automatically
34
+ - ✅ Install files to the correct location
35
+ - ✅ Check for missing dependencies
36
+ - ✅ Offer to install missing packages
37
+
38
+ ### Supported Package Managers
39
+
40
+ The CLI automatically detects and uses your preferred package manager:
41
+
42
+ - npm
43
+ - pnpm
44
+ - yarn
45
+ - bun
46
+
47
+ ## 🛠️ How It Works
48
+
49
+ 1. **Directory Detection**: The CLI checks for `components.json` and respects your aliases
50
+ 2. **Component Fetching**: Downloads component data from beste.co
51
+ 3. **File Installation**: Places files in the appropriate directory structure
52
+ 4. **Dependency Check**: Compares required packages with your `package.json`
53
+ 5. **Installation**: Offers to install missing dependencies with your package manager
54
+
55
+ ## 📋 Requirements
56
+
57
+ - Node.js 18 or higher
58
+ - A React/Next.js project with shadcn/ui setup (recommended)
59
+
60
+ ## 🤝 Contributing
61
+
62
+ Contributions are welcome! Please feel free to submit issues or pull requests.
63
+
64
+ ## 📄 License
65
+
66
+ MIT © [compbyter](https://github.com/compbyter)
67
+
68
+ ## 🔗 Links
69
+
70
+ - [Official Website](https://ui.beste.co)
71
+ - [GitHub Repository](https://github.com/compbyter/beste-cli)
72
+ - [npm Package](https://www.npmjs.com/package/beste-cli)
73
+ - [Report Issues](https://github.com/compbyter/beste-cli/issues)
74
+
75
+ ---
76
+
77
+ Made with ❤️ for the beste.co community
package/bin/index.js ADDED
@@ -0,0 +1,141 @@
1
+ #!/usr/bin/env node
2
+
3
+ import { Command } from 'commander';
4
+ import chalk from 'chalk';
5
+ import fs from 'fs-extra';
6
+ import path from 'path';
7
+ import ora from 'ora';
8
+ import { confirm } from '@inquirer/prompts';
9
+ import { execSync } from 'child_process';
10
+
11
+ const program = new Command();
12
+
13
+ program
14
+ .name('beste')
15
+ .description('beste.co Premium CLI')
16
+ .version('0.1.0');
17
+
18
+ async function getTargetDirectory() {
19
+ const cwd = process.cwd();
20
+ const componentsJsonPath = path.join(cwd, 'components.json');
21
+ const fallbackPath = path.join(cwd, 'src', 'components', 'beste');
22
+
23
+ try {
24
+ if (await fs.pathExists(componentsJsonPath)) {
25
+ const config = await fs.readJson(componentsJsonPath);
26
+ const componentsAlias = config.aliases?.components;
27
+
28
+ if (componentsAlias) {
29
+ const cleanPath = componentsAlias.replace(/^[@~]\//, '');
30
+ const isUsingSrc = await fs.pathExists(path.join(cwd, 'src'));
31
+ return path.join(cwd, isUsingSrc ? 'src' : '', cleanPath, 'beste');
32
+ }
33
+ }
34
+ } catch (error) {
35
+ // Sessizce fallback'e geç
36
+ }
37
+ return fallbackPath;
38
+ }
39
+
40
+ program
41
+ .command('add <urlOrName>')
42
+ .description('Adds a new premium component to the project')
43
+ .action(async (urlOrName) => {
44
+ const spinner = ora(chalk.blue('Fetching component...')).start();
45
+
46
+ try {
47
+ let componentData;
48
+
49
+ if (urlOrName.startsWith('http')) {
50
+ const response = await fetch(urlOrName);
51
+ if (!response.ok) throw new Error('Component not found at the provided URL!');
52
+
53
+ componentData = await response.json();
54
+ } else {
55
+ throw new Error('Please use a full URL for now (e.g., https://ui.beste.co/r/footer9).');
56
+ }
57
+
58
+ if (!componentData.files || !Array.isArray(componentData.files)) {
59
+ throw new Error('Invalid component format. "files" array is missing.');
60
+ }
61
+
62
+ const targetBaseDir = await getTargetDirectory();
63
+
64
+ for (const file of componentData.files) {
65
+ const fileName = path.basename(file.path);
66
+
67
+ let finalPath;
68
+ if (file.target) {
69
+ const targetSubDir = path.dirname(file.target).replace(/^components\//, '');
70
+ const fullTargetDir = path.join(targetBaseDir, '..', targetSubDir);
71
+ await fs.ensureDir(fullTargetDir);
72
+ finalPath = path.join(fullTargetDir, fileName);
73
+ } else {
74
+ await fs.ensureDir(targetBaseDir);
75
+ finalPath = path.join(targetBaseDir, fileName);
76
+ }
77
+
78
+ await fs.writeFile(finalPath, file.content);
79
+
80
+ const relativePath = path.relative(process.cwd(), finalPath);
81
+ spinner.succeed(chalk.green(`${fileName} added successfully!`));
82
+ console.log(chalk.gray(` └─ Location: ./${relativePath.replace(/\\/g, '/')}`));
83
+ }
84
+
85
+ // --- YENİ EKLENEN AKILLI BAĞIMLILIK KONTROLÜ ---
86
+ const allDependencies = [];
87
+ if (componentData.dependencies) allDependencies.push(...componentData.dependencies);
88
+ if (componentData.registryDependencies) allDependencies.push(...componentData.registryDependencies);
89
+
90
+ const uniqueDeps = [...new Set(allDependencies)];
91
+
92
+ if (uniqueDeps.length > 0) {
93
+ const pkgPath = path.join(process.cwd(), 'package.json');
94
+ let missingDeps = uniqueDeps;
95
+
96
+ // Projenin package.json dosyasını oku ve yüklü olanları filtrele
97
+ if (await fs.pathExists(pkgPath)) {
98
+ const pkg = await fs.readJson(pkgPath);
99
+ const installedDeps = { ...pkg.dependencies, ...pkg.devDependencies };
100
+ missingDeps = uniqueDeps.filter(dep => !installedDeps[dep]);
101
+ }
102
+
103
+ if (missingDeps.length > 0) {
104
+ console.log(chalk.yellow(`\n📦 These packages are missing: ${missingDeps.join(', ')}`));
105
+
106
+ // Kullanıcıya sor
107
+ const shouldInstall = await confirm({ message: 'Do you want to install these packages now?' });
108
+
109
+ if (shouldInstall) {
110
+ const installSpinner = ora('Installing packages...').start();
111
+ try {
112
+ // Paket yöneticisini akıllı tespit et
113
+ const cwd = process.cwd();
114
+ const isPnpm = await fs.pathExists(path.join(cwd, 'pnpm-lock.yaml'));
115
+ const isYarn = await fs.pathExists(path.join(cwd, 'yarn.lock'));
116
+ const isBun = await fs.pathExists(path.join(cwd, 'bun.lockb'));
117
+
118
+ const pmCommand = isPnpm ? 'pnpm add' : isYarn ? 'yarn add' : isBun ? 'bun add' : 'npm install';
119
+
120
+ // Kurulumu arka planda çalıştır
121
+ execSync(`${pmCommand} ${missingDeps.join(' ')}`, { stdio: 'pipe' });
122
+ installSpinner.succeed(chalk.green('Packages installed successfully! 🚀'));
123
+ } catch (error) {
124
+ installSpinner.fail(chalk.red('Failed to install packages.'));
125
+ console.log(chalk.white(`Please install manually: npm install ${missingDeps.join(' ')}`));
126
+ }
127
+ } else {
128
+ console.log(chalk.gray(`\nOkay, you can install them manually using this command:`));
129
+ console.log(chalk.white(` npm install ${missingDeps.join(' ')}`));
130
+ }
131
+ } else {
132
+ console.log(chalk.green(`\n✅ All required packages ( ${uniqueDeps.join(', ')} ) are already installed in the project!`));
133
+ }
134
+ }
135
+
136
+ } catch (error) {
137
+ spinner.fail(chalk.red(`Error: ${error.message}`));
138
+ }
139
+ });
140
+
141
+ program.parse();
package/package.json ADDED
@@ -0,0 +1,49 @@
1
+ {
2
+ "name": "beste-cli",
3
+ "version": "0.1.0",
4
+ "description": "CLI for beste.co - Install offical beste.co components",
5
+ "author": "compbyter",
6
+ "license": "MIT",
7
+ "type": "module",
8
+ "bin": {
9
+ "beste": "bin/index.js"
10
+ },
11
+ "files": [
12
+ "bin",
13
+ "src"
14
+ ],
15
+ "scripts": {
16
+ "test": "echo \"Error: no test specified\" && exit 1"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/compbyter/beste-cli.git"
21
+ },
22
+ "homepage": "https://ui.beste.co",
23
+ "bugs": {
24
+ "url": "https://github.com/compbyter/beste-cli/issues"
25
+ },
26
+ "keywords": [
27
+ "cli",
28
+ "beste",
29
+ "beste.co",
30
+ "react",
31
+ "nextjs",
32
+ "ui",
33
+ "components",
34
+ "shadcn",
35
+ "shadcn-ui",
36
+ "premium-components",
37
+ "beste-ui",
38
+ "beste-components",
39
+ "beste-blocks",
40
+ "beste-cli"
41
+ ],
42
+ "dependencies": {
43
+ "@inquirer/prompts": "^7.10.1",
44
+ "chalk": "^5.6.2",
45
+ "commander": "^14.0.3",
46
+ "fs-extra": "^11.3.3",
47
+ "ora": "^9.3.0"
48
+ }
49
+ }