zerozeeker 2.2.7 → 2.2.9
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 +4 -18
- package/dist/index.js +145 -10
- package/package.json +10 -7
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# ZeroZeeker Components
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Zero-config CLI** for installing production-ready UI components into your React or Next.js projects.
|
|
4
|
+
|
|
5
|
+
**No setup required. No shadcn/ui required. Just install and go.** ✨
|
|
4
6
|
|
|
5
7
|
[](https://www.npmjs.com/package/zerozeeker)
|
|
6
8
|
[](https://www.typescriptlang.org/)
|
|
@@ -90,17 +92,8 @@ Before using ZeroZeeker components, ensure you have:
|
|
|
90
92
|
|
|
91
93
|
- Node.js 18 or higher
|
|
92
94
|
- An existing React or Next.js project
|
|
93
|
-
- shadcn/ui initialized in your project
|
|
94
95
|
- Tailwind CSS configured
|
|
95
96
|
|
|
96
|
-
### Setup shadcn/ui
|
|
97
|
-
|
|
98
|
-
If you haven't initialized shadcn/ui yet:
|
|
99
|
-
|
|
100
|
-
```bash
|
|
101
|
-
npx shadcn-ui@latest init
|
|
102
|
-
```
|
|
103
|
-
|
|
104
97
|
---
|
|
105
98
|
|
|
106
99
|
## How to Use Installed Components
|
|
@@ -119,7 +112,7 @@ export default function App() {
|
|
|
119
112
|
}
|
|
120
113
|
```
|
|
121
114
|
|
|
122
|
-
All components follow
|
|
115
|
+
All components follow standard conventions. Import from `@/components/ui/<component-name>`.
|
|
123
116
|
|
|
124
117
|
---
|
|
125
118
|
|
|
@@ -158,13 +151,6 @@ Use the full npx command:
|
|
|
158
151
|
npx zerozeeker list
|
|
159
152
|
```
|
|
160
153
|
|
|
161
|
-
### shadcn/ui not initialized
|
|
162
|
-
|
|
163
|
-
Initialize shadcn/ui first:
|
|
164
|
-
```bash
|
|
165
|
-
npx shadcn-ui@latest init
|
|
166
|
-
```
|
|
167
|
-
|
|
168
154
|
### Component won't install
|
|
169
155
|
|
|
170
156
|
Verify the exact component name:
|
package/dist/index.js
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
// index.ts
|
|
4
4
|
import { Command } from "commander";
|
|
5
5
|
import { execSync } from "child_process";
|
|
6
|
+
import { existsSync, mkdirSync, writeFileSync } from "fs";
|
|
7
|
+
import { join, dirname } from "path";
|
|
6
8
|
import ora from "ora";
|
|
7
9
|
import chalk from "chalk";
|
|
8
10
|
var REGISTRY_URL = "https://www.zerozeeker.com/r";
|
|
@@ -15,9 +17,83 @@ var COMPONENTS = [
|
|
|
15
17
|
"circle-reveal-button",
|
|
16
18
|
"index"
|
|
17
19
|
];
|
|
20
|
+
async function fetchRegistry(url) {
|
|
21
|
+
const response = await fetch(url);
|
|
22
|
+
if (!response.ok) {
|
|
23
|
+
throw new Error(`Failed to fetch registry: ${response.statusText}`);
|
|
24
|
+
}
|
|
25
|
+
return response.json();
|
|
26
|
+
}
|
|
27
|
+
function ensureDir(filePath) {
|
|
28
|
+
const dir = dirname(filePath);
|
|
29
|
+
if (!existsSync(dir)) {
|
|
30
|
+
mkdirSync(dir, { recursive: true });
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
function findProjectRoot() {
|
|
34
|
+
let currentDir = process.cwd();
|
|
35
|
+
while (currentDir !== dirname(currentDir)) {
|
|
36
|
+
if (existsSync(join(currentDir, "package.json"))) {
|
|
37
|
+
return currentDir;
|
|
38
|
+
}
|
|
39
|
+
currentDir = dirname(currentDir);
|
|
40
|
+
}
|
|
41
|
+
throw new Error("Could not find project root (no package.json found)");
|
|
42
|
+
}
|
|
43
|
+
function installDependencies(deps) {
|
|
44
|
+
if (deps.length === 0) return;
|
|
45
|
+
console.log(chalk.dim(` Installing dependencies: ${deps.join(", ")}`));
|
|
46
|
+
try {
|
|
47
|
+
execSync(`npm install ${deps.join(" ")}`, {
|
|
48
|
+
stdio: "pipe",
|
|
49
|
+
encoding: "utf-8"
|
|
50
|
+
});
|
|
51
|
+
} catch {
|
|
52
|
+
console.warn(chalk.yellow(` Warning: Failed to auto-install dependencies. Install manually: npm install ${deps.join(" ")}`));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
async function installRegistryDependencies(deps, projectRoot, installed = /* @__PURE__ */ new Set()) {
|
|
56
|
+
const allFiles = [];
|
|
57
|
+
const allNpmDeps = [];
|
|
58
|
+
for (const dep of deps) {
|
|
59
|
+
if (installed.has(dep)) continue;
|
|
60
|
+
installed.add(dep);
|
|
61
|
+
const url = `${REGISTRY_URL}/${dep}.json`;
|
|
62
|
+
try {
|
|
63
|
+
const registry = await fetchRegistry(url);
|
|
64
|
+
if (registry.registryDependencies && registry.registryDependencies.length > 0) {
|
|
65
|
+
const nested = await installRegistryDependencies(
|
|
66
|
+
registry.registryDependencies,
|
|
67
|
+
projectRoot,
|
|
68
|
+
installed
|
|
69
|
+
);
|
|
70
|
+
allFiles.push(...nested.files);
|
|
71
|
+
allNpmDeps.push(...nested.npmDeps);
|
|
72
|
+
}
|
|
73
|
+
if (registry.files && registry.files.length > 0) {
|
|
74
|
+
for (const file of registry.files) {
|
|
75
|
+
const targetPath = file.target || file.path;
|
|
76
|
+
const fullPath = join(projectRoot, targetPath);
|
|
77
|
+
if (existsSync(fullPath)) {
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
ensureDir(fullPath);
|
|
81
|
+
writeFileSync(fullPath, file.content, "utf-8");
|
|
82
|
+
allFiles.push(targetPath);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
if (registry.dependencies) {
|
|
86
|
+
allNpmDeps.push(...registry.dependencies);
|
|
87
|
+
}
|
|
88
|
+
} catch (error) {
|
|
89
|
+
console.warn(chalk.yellow(` Warning: Could not install registry dependency "${dep}"`));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
return { files: allFiles, npmDeps: allNpmDeps };
|
|
93
|
+
}
|
|
18
94
|
var program = new Command();
|
|
19
|
-
program.name("zerozeeker").description("CLI for installing ZeroZeeker UI components - because life is too short for boring interfaces").version("1.0
|
|
20
|
-
program.command("add <component>").description("Add a component from ZeroZeeker registry").action((component) => {
|
|
95
|
+
program.name("zerozeeker").description("CLI for installing ZeroZeeker UI components - because life is too short for boring interfaces").version("2.1.0");
|
|
96
|
+
program.command("add <component>").description("Add a component from ZeroZeeker registry").action(async (component) => {
|
|
21
97
|
if (!COMPONENTS.includes(component)) {
|
|
22
98
|
console.error(chalk.red(`Component "${component}" does not exist in this dimension.`));
|
|
23
99
|
console.log(chalk.dim("\nHere are the components that actually exist:"));
|
|
@@ -28,18 +104,77 @@ program.command("add <component>").description("Add a component from ZeroZeeker
|
|
|
28
104
|
process.exit(1);
|
|
29
105
|
}
|
|
30
106
|
const url = `${REGISTRY_URL}/${component}.json`;
|
|
31
|
-
const spinner = ora(`Installing ${chalk.cyan(component)}
|
|
107
|
+
const spinner = ora(`Installing ${chalk.cyan(component)}...`).start();
|
|
32
108
|
try {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
109
|
+
const projectRoot = findProjectRoot();
|
|
110
|
+
spinner.text = `Fetching ${chalk.cyan(component)} from registry...`;
|
|
111
|
+
const registry = await fetchRegistry(url);
|
|
112
|
+
const filesInstalled = [];
|
|
113
|
+
const allDependencies = [...registry.dependencies || []];
|
|
114
|
+
if (registry.registryDependencies && registry.registryDependencies.length > 0) {
|
|
115
|
+
spinner.text = `Installing registry dependencies...`;
|
|
116
|
+
const registryResult = await installRegistryDependencies(
|
|
117
|
+
registry.registryDependencies,
|
|
118
|
+
projectRoot
|
|
119
|
+
);
|
|
120
|
+
filesInstalled.push(...registryResult.files);
|
|
121
|
+
allDependencies.push(...registryResult.npmDeps);
|
|
122
|
+
}
|
|
123
|
+
if (registry.files && registry.files.length > 0) {
|
|
124
|
+
spinner.text = `Installing ${chalk.cyan(component)} files...`;
|
|
125
|
+
for (const file of registry.files) {
|
|
126
|
+
const targetPath = file.target || file.path;
|
|
127
|
+
const fullPath = join(projectRoot, targetPath);
|
|
128
|
+
if (existsSync(fullPath)) {
|
|
129
|
+
spinner.stop();
|
|
130
|
+
console.warn(chalk.yellow(`
|
|
131
|
+
\u26A0 File already exists: ${targetPath}`));
|
|
132
|
+
console.log(chalk.dim(" Skipping to avoid overwriting your changes."));
|
|
133
|
+
console.log(chalk.dim(` To force reinstall: delete the file and run the command again.
|
|
134
|
+
`));
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
ensureDir(fullPath);
|
|
138
|
+
writeFileSync(fullPath, file.content, "utf-8");
|
|
139
|
+
filesInstalled.push(targetPath);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
const uniqueDeps = [...new Set(allDependencies)];
|
|
143
|
+
if (uniqueDeps.length > 0) {
|
|
144
|
+
spinner.text = "Installing npm dependencies...";
|
|
145
|
+
installDependencies(uniqueDeps);
|
|
146
|
+
}
|
|
37
147
|
spinner.stop();
|
|
38
|
-
console.log(chalk.green(`
|
|
148
|
+
console.log(chalk.green(`
|
|
149
|
+
\u2713 Successfully installed ${component}`));
|
|
150
|
+
if (filesInstalled.length > 0) {
|
|
151
|
+
console.log(chalk.dim("\n Files added:"));
|
|
152
|
+
filesInstalled.forEach((f) => {
|
|
153
|
+
console.log(chalk.cyan(` ${f}`));
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
if (uniqueDeps.length > 0) {
|
|
157
|
+
console.log(chalk.dim("\n Dependencies installed:"));
|
|
158
|
+
uniqueDeps.forEach((d) => {
|
|
159
|
+
console.log(chalk.cyan(` ${d}`));
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
console.log(chalk.dim("\n Now go make something beautiful. \u2728\n"));
|
|
39
163
|
} catch (error) {
|
|
40
164
|
spinner.stop();
|
|
41
|
-
console.error(chalk.red(`
|
|
42
|
-
|
|
165
|
+
console.error(chalk.red(`
|
|
166
|
+
\u2717 Failed to install ${component}`));
|
|
167
|
+
if (error instanceof Error) {
|
|
168
|
+
if (error.message.includes("package.json")) {
|
|
169
|
+
console.log(chalk.dim("\n Make sure you're in a React/Next.js project directory."));
|
|
170
|
+
} else if (error.message.includes("fetch")) {
|
|
171
|
+
console.log(chalk.dim("\n Check your internet connection and try again."));
|
|
172
|
+
} else {
|
|
173
|
+
console.log(chalk.dim(`
|
|
174
|
+
${error.message}`));
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
console.log(chalk.dim("\n Need help? https://www.zerozeeker.com/docs\n"));
|
|
43
178
|
process.exit(1);
|
|
44
179
|
}
|
|
45
180
|
});
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zerozeeker",
|
|
3
|
-
"version": "2.2.
|
|
4
|
-
"description": "CLI for installing ZeroZeeker UI components",
|
|
3
|
+
"version": "2.2.9",
|
|
4
|
+
"description": "Zero-config CLI for installing ZeroZeeker UI components. No shadcn required.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
7
7
|
"zerozeeker": "dist/index.js"
|
|
@@ -16,21 +16,24 @@
|
|
|
16
16
|
"prepublishOnly": "npm run build"
|
|
17
17
|
},
|
|
18
18
|
"keywords": [
|
|
19
|
-
"
|
|
20
|
-
"components",
|
|
19
|
+
"zerozeeker",
|
|
21
20
|
"ui",
|
|
22
|
-
"
|
|
21
|
+
"components",
|
|
22
|
+
"react",
|
|
23
|
+
"tailwind",
|
|
24
|
+
"typescript"
|
|
23
25
|
],
|
|
24
26
|
"author": "ZeroZeeker",
|
|
25
27
|
"license": "MIT",
|
|
26
28
|
"dependencies": {
|
|
29
|
+
"chalk": "^5.3.0",
|
|
27
30
|
"commander": "^12.1.0",
|
|
28
|
-
"ora": "^8.0.1"
|
|
29
|
-
"chalk": "^5.3.0"
|
|
31
|
+
"ora": "^8.0.1"
|
|
30
32
|
},
|
|
31
33
|
"devDependencies": {
|
|
32
34
|
"@types/node": "^20.11.5",
|
|
33
35
|
"tsup": "^8.0.1",
|
|
36
|
+
"tsx": "^4.21.0",
|
|
34
37
|
"typescript": "^5.3.3"
|
|
35
38
|
},
|
|
36
39
|
"engines": {
|