zerozeeker 2.2.0 → 2.2.2
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 +147 -79
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -5,6 +5,7 @@ import { Command } from "commander";
|
|
|
5
5
|
import { execSync } from "child_process";
|
|
6
6
|
import { existsSync, mkdirSync, writeFileSync, readFileSync } from "fs";
|
|
7
7
|
import { join, dirname } from "path";
|
|
8
|
+
import readline from "readline";
|
|
8
9
|
import ora from "ora";
|
|
9
10
|
import chalk from "chalk";
|
|
10
11
|
var REGISTRY_URL = "https://www.zerozeeker.com/r";
|
|
@@ -49,9 +50,21 @@ function installDependencies(deps) {
|
|
|
49
50
|
encoding: "utf-8"
|
|
50
51
|
});
|
|
51
52
|
} catch {
|
|
52
|
-
console.warn(chalk.yellow(`
|
|
53
|
+
console.warn(chalk.yellow(` [!] Failed to auto-install dependencies. Install manually: npm install ${deps.join(" ")}`));
|
|
53
54
|
}
|
|
54
55
|
}
|
|
56
|
+
async function askYesNo(question, defaultYes = false) {
|
|
57
|
+
const rl = readline.createInterface({ input: process.stdin, output: process.stdout });
|
|
58
|
+
return new Promise((resolve) => {
|
|
59
|
+
rl.question(`${question} (${defaultYes ? "Y/n" : "y/N"}): `, (answer) => {
|
|
60
|
+
rl.close();
|
|
61
|
+
const a = answer.trim().toLowerCase();
|
|
62
|
+
if (a === "") return resolve(defaultYes);
|
|
63
|
+
if (["y", "yes"].includes(a)) return resolve(true);
|
|
64
|
+
return resolve(false);
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
}
|
|
55
68
|
async function installRegistryDependencies(deps, projectRoot, installed = /* @__PURE__ */ new Set()) {
|
|
56
69
|
const allFiles = [];
|
|
57
70
|
const allNpmDeps = [];
|
|
@@ -85,103 +98,166 @@ async function installRegistryDependencies(deps, projectRoot, installed = /* @__
|
|
|
85
98
|
if (registry.dependencies) {
|
|
86
99
|
allNpmDeps.push(...registry.dependencies);
|
|
87
100
|
}
|
|
88
|
-
} catch
|
|
89
|
-
console.warn(chalk.yellow(`
|
|
101
|
+
} catch {
|
|
102
|
+
console.warn(chalk.yellow(` [!] Could not install registry dependency "${dep}"`));
|
|
90
103
|
}
|
|
91
104
|
}
|
|
92
105
|
return { files: allFiles, npmDeps: allNpmDeps };
|
|
93
106
|
}
|
|
107
|
+
function checkTypeScriptConfig(projectRoot) {
|
|
108
|
+
const tsconfigPath = join(projectRoot, "tsconfig.json");
|
|
109
|
+
if (!existsSync(tsconfigPath)) {
|
|
110
|
+
return { name: "TypeScript", passed: false, message: "tsconfig.json not found" };
|
|
111
|
+
}
|
|
112
|
+
try {
|
|
113
|
+
const tsconfig = JSON.parse(readFileSync(tsconfigPath, "utf-8"));
|
|
114
|
+
const paths = tsconfig.compilerOptions?.paths || {};
|
|
115
|
+
const hasComponentsAlias = paths["@/components/*"] || paths["@/components"];
|
|
116
|
+
const hasLibAlias = paths["@/lib/*"] || paths["@/lib"];
|
|
117
|
+
if (hasComponentsAlias && hasLibAlias) {
|
|
118
|
+
return { name: "TypeScript paths", passed: true };
|
|
119
|
+
}
|
|
120
|
+
return {
|
|
121
|
+
name: "TypeScript paths",
|
|
122
|
+
passed: false,
|
|
123
|
+
message: "Missing @/components or @/lib path aliases"
|
|
124
|
+
};
|
|
125
|
+
} catch {
|
|
126
|
+
return { name: "TypeScript config", passed: false, message: "Invalid tsconfig.json" };
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
function checkTailwindConfig(projectRoot) {
|
|
130
|
+
const tailwindConfigs = [
|
|
131
|
+
"tailwind.config.ts",
|
|
132
|
+
"tailwind.config.js",
|
|
133
|
+
"tailwind.config.mjs",
|
|
134
|
+
"tailwind.config.cjs"
|
|
135
|
+
];
|
|
136
|
+
const hasTailwind = tailwindConfigs.some((config) => existsSync(join(projectRoot, config)));
|
|
137
|
+
return hasTailwind ? { name: "Tailwind CSS", passed: true } : { name: "Tailwind CSS", passed: false, message: "Config file not found" };
|
|
138
|
+
}
|
|
139
|
+
function checkFramework(projectRoot) {
|
|
140
|
+
const packageJsonPath = join(projectRoot, "package.json");
|
|
141
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
142
|
+
const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
|
|
143
|
+
if (deps.next) {
|
|
144
|
+
return { name: "Next.js", passed: true };
|
|
145
|
+
}
|
|
146
|
+
if (deps.react) {
|
|
147
|
+
return { name: "React", passed: true };
|
|
148
|
+
}
|
|
149
|
+
return { name: "React/Next.js", passed: false, message: "Not found in dependencies" };
|
|
150
|
+
}
|
|
151
|
+
function displaySetupHelp(checks) {
|
|
152
|
+
const tsCheck = checks.find((c) => c.name === "TypeScript");
|
|
153
|
+
const tailwindCheck = checks.find((c) => c.name === "Tailwind CSS");
|
|
154
|
+
if (tsCheck && !tsCheck.passed) {
|
|
155
|
+
console.log(chalk.dim("Install TypeScript:"));
|
|
156
|
+
console.log(chalk.white(" npm install -D typescript @types/node @types/react"));
|
|
157
|
+
console.log(chalk.dim("\nCreate tsconfig.json with path aliases:"));
|
|
158
|
+
console.log(chalk.white(" npx tsc --init"));
|
|
159
|
+
}
|
|
160
|
+
if (tailwindCheck && !tailwindCheck.passed) {
|
|
161
|
+
console.log(chalk.dim("\nInstall Tailwind CSS:"));
|
|
162
|
+
console.log(chalk.white(" npm install -D tailwindcss postcss autoprefixer"));
|
|
163
|
+
console.log(chalk.white(" npx tailwindcss init -p"));
|
|
164
|
+
}
|
|
165
|
+
console.log(chalk.dim("\nOr create a new Next.js project:"));
|
|
166
|
+
console.log(chalk.white(" npx create-next-app@latest --typescript --tailwind\n"));
|
|
167
|
+
}
|
|
168
|
+
async function autoFixSetup(projectRoot, needsTypeScript, needsTailwind, spinner) {
|
|
169
|
+
if (needsTypeScript) {
|
|
170
|
+
spinner.text = "Installing TypeScript and types...";
|
|
171
|
+
execSync("npm install -D typescript @types/node @types/react", { stdio: "inherit" });
|
|
172
|
+
}
|
|
173
|
+
const tsconfigPath = join(projectRoot, "tsconfig.json");
|
|
174
|
+
let tsconfig = {};
|
|
175
|
+
if (existsSync(tsconfigPath)) {
|
|
176
|
+
try {
|
|
177
|
+
tsconfig = JSON.parse(readFileSync(tsconfigPath, "utf-8"));
|
|
178
|
+
} catch {
|
|
179
|
+
tsconfig = {};
|
|
180
|
+
}
|
|
181
|
+
} else {
|
|
182
|
+
spinner.text = "Creating tsconfig.json...";
|
|
183
|
+
tsconfig = { compilerOptions: {} };
|
|
184
|
+
writeFileSync(tsconfigPath, JSON.stringify(tsconfig, null, 2), "utf-8");
|
|
185
|
+
}
|
|
186
|
+
tsconfig.compilerOptions = tsconfig.compilerOptions || {};
|
|
187
|
+
tsconfig.compilerOptions.baseUrl = tsconfig.compilerOptions.baseUrl || ".";
|
|
188
|
+
tsconfig.compilerOptions.paths = tsconfig.compilerOptions.paths || {};
|
|
189
|
+
tsconfig.compilerOptions.paths["@/components/*"] = ["components/*"];
|
|
190
|
+
tsconfig.compilerOptions.paths["@/lib/*"] = ["lib/*"];
|
|
191
|
+
writeFileSync(tsconfigPath, JSON.stringify(tsconfig, null, 2), "utf-8");
|
|
192
|
+
if (needsTailwind) {
|
|
193
|
+
spinner.text = "Installing Tailwind CSS...";
|
|
194
|
+
execSync("npm install -D tailwindcss postcss autoprefixer", { stdio: "inherit" });
|
|
195
|
+
spinner.text = "Initializing Tailwind config...";
|
|
196
|
+
execSync("npx tailwindcss init -p", { stdio: "inherit" });
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
var COMPONENT_DESCRIPTIONS = {
|
|
200
|
+
"rainbow-button": "Animated rainbow gradient border - for when one color just will not cut it",
|
|
201
|
+
"shimmer-button": "Moving border glow effect - subtle flex, maximum impact",
|
|
202
|
+
"magnetic-button": "Cursor-following magnetic effect - it literally chases your mouse",
|
|
203
|
+
"expand-button": "Expanding pill animation - small to big, just like your startup",
|
|
204
|
+
"flip-button": "3D flip card effect - because flat is boring",
|
|
205
|
+
"circle-reveal-button": "Icon to pill expansion - the element of surprise"
|
|
206
|
+
};
|
|
94
207
|
var program = new Command();
|
|
95
208
|
program.name("zerozeeker").description("CLI for installing ZeroZeeker UI components - because life is too short for boring interfaces").version("2.2.0");
|
|
96
209
|
program.command("init").description("Initialize ZeroZeeker in your project").action(async () => {
|
|
97
210
|
const spinner = ora("Checking project setup...").start();
|
|
98
211
|
try {
|
|
99
212
|
const projectRoot = findProjectRoot();
|
|
100
|
-
const checks = [
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
const tsconfig = JSON.parse(readFileSync(tsconfigPath, "utf-8"));
|
|
105
|
-
const paths = tsconfig.compilerOptions?.paths || {};
|
|
106
|
-
const hasComponentsAlias = paths["@/components/*"] || paths["@/components"];
|
|
107
|
-
const hasLibAlias = paths["@/lib/*"] || paths["@/lib"];
|
|
108
|
-
if (hasComponentsAlias && hasLibAlias) {
|
|
109
|
-
checks.push({ name: "TypeScript paths", passed: true });
|
|
110
|
-
} else {
|
|
111
|
-
checks.push({
|
|
112
|
-
name: "TypeScript paths",
|
|
113
|
-
passed: false,
|
|
114
|
-
message: "Missing @/components or @/lib path aliases"
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
} catch {
|
|
118
|
-
checks.push({ name: "TypeScript config", passed: false, message: "Invalid tsconfig.json" });
|
|
119
|
-
}
|
|
120
|
-
} else {
|
|
121
|
-
checks.push({ name: "TypeScript", passed: false, message: "tsconfig.json not found" });
|
|
122
|
-
}
|
|
123
|
-
const tailwindConfigs = [
|
|
124
|
-
"tailwind.config.ts",
|
|
125
|
-
"tailwind.config.js",
|
|
126
|
-
"tailwind.config.mjs",
|
|
127
|
-
"tailwind.config.cjs"
|
|
213
|
+
const checks = [
|
|
214
|
+
checkTypeScriptConfig(projectRoot),
|
|
215
|
+
checkTailwindConfig(projectRoot),
|
|
216
|
+
checkFramework(projectRoot)
|
|
128
217
|
];
|
|
129
|
-
const hasTailwind = tailwindConfigs.some((config) => existsSync(join(projectRoot, config)));
|
|
130
|
-
if (hasTailwind) {
|
|
131
|
-
checks.push({ name: "Tailwind CSS", passed: true });
|
|
132
|
-
} else {
|
|
133
|
-
checks.push({ name: "Tailwind CSS", passed: false, message: "Config file not found" });
|
|
134
|
-
}
|
|
135
|
-
const packageJsonPath = join(projectRoot, "package.json");
|
|
136
|
-
const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
|
|
137
|
-
const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
|
|
138
|
-
const hasReact = deps.react;
|
|
139
|
-
const hasNext = deps.next;
|
|
140
|
-
if (hasReact || hasNext) {
|
|
141
|
-
checks.push({
|
|
142
|
-
name: hasNext ? "Next.js" : "React",
|
|
143
|
-
passed: true
|
|
144
|
-
});
|
|
145
|
-
} else {
|
|
146
|
-
checks.push({ name: "React/Next.js", passed: false, message: "Not found in dependencies" });
|
|
147
|
-
}
|
|
148
218
|
spinner.stop();
|
|
149
|
-
console.log(chalk.bold("\n
|
|
219
|
+
console.log(chalk.bold("\n[*] Project Setup Check\n"));
|
|
150
220
|
let allPassed = true;
|
|
151
221
|
for (const check of checks) {
|
|
152
222
|
if (check.passed) {
|
|
153
|
-
console.log(chalk.green(`
|
|
223
|
+
console.log(chalk.green(` [+] ${check.name}`));
|
|
154
224
|
} else {
|
|
155
|
-
console.log(chalk.red(`
|
|
225
|
+
console.log(chalk.red(` [x] ${check.name}${check.message ? `: ${check.message}` : ""}`));
|
|
156
226
|
allPassed = false;
|
|
157
227
|
}
|
|
158
228
|
}
|
|
159
229
|
if (allPassed) {
|
|
160
|
-
console.log(chalk.green("\n
|
|
230
|
+
console.log(chalk.green("\n[*] Your project is ready for ZeroZeeker!\n"));
|
|
161
231
|
console.log(chalk.dim("Get started:"));
|
|
162
232
|
console.log(chalk.cyan(" npx zerozeeker add rainbow-button"));
|
|
163
233
|
console.log(chalk.dim("\nList all components:"));
|
|
164
234
|
console.log(chalk.cyan(" npx zerozeeker list\n"));
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
console.log(chalk.yellow("\n[!] Some setup issues detected\n"));
|
|
238
|
+
displaySetupHelp(checks);
|
|
239
|
+
const needsTypeScript = !checks.find(
|
|
240
|
+
(c) => c.name === "TypeScript" || c.name === "TypeScript paths" || c.name === "TypeScript config"
|
|
241
|
+
)?.passed;
|
|
242
|
+
const needsTailwind = !checks.find((c) => c.name === "Tailwind CSS")?.passed;
|
|
243
|
+
const doAuto = await askYesNo("Would you like ZeroZeeker to try to automatically fix these issues now?", true);
|
|
244
|
+
if (!doAuto) {
|
|
245
|
+
process.exit(1);
|
|
246
|
+
}
|
|
247
|
+
spinner.start();
|
|
248
|
+
try {
|
|
249
|
+
await autoFixSetup(projectRoot, needsTypeScript, needsTailwind, spinner);
|
|
250
|
+
spinner.stop();
|
|
251
|
+
console.log(chalk.green("\n[+] Auto-fix complete. Re-run `npx zerozeeker init` to re-check, or proceed to install components."));
|
|
252
|
+
process.exit(0);
|
|
253
|
+
} catch {
|
|
254
|
+
spinner.stop();
|
|
255
|
+
console.error(chalk.red("\n[x] Auto-fix failed. See errors above."));
|
|
180
256
|
process.exit(1);
|
|
181
257
|
}
|
|
182
258
|
} catch (error) {
|
|
183
259
|
spinner.stop();
|
|
184
|
-
console.error(chalk.red("\n
|
|
260
|
+
console.error(chalk.red("\n[x] Initialization failed\n"));
|
|
185
261
|
if (error instanceof Error && error.message.includes("package.json")) {
|
|
186
262
|
console.log(chalk.dim("Make sure you're in a React/Next.js project directory.\n"));
|
|
187
263
|
} else {
|
|
@@ -279,17 +355,9 @@ program.command("add <component>").description("Add a component from ZeroZeeker
|
|
|
279
355
|
program.command("list").description("List all available components").action(() => {
|
|
280
356
|
console.log(chalk.bold("\nZeroZeeker UI Components\n"));
|
|
281
357
|
console.log(chalk.dim("Modern, polished components that make users actually want to interact.\n"));
|
|
282
|
-
const descriptions = {
|
|
283
|
-
"rainbow-button": "Animated rainbow gradient border - for when one color just will not cut it",
|
|
284
|
-
"shimmer-button": "Moving border glow effect - subtle flex, maximum impact",
|
|
285
|
-
"magnetic-button": "Cursor-following magnetic effect - it literally chases your mouse",
|
|
286
|
-
"expand-button": "Expanding pill animation - small to big, just like your startup",
|
|
287
|
-
"flip-button": "3D flip card effect - because flat is boring",
|
|
288
|
-
"circle-reveal-button": "Icon to pill expansion - the element of surprise"
|
|
289
|
-
};
|
|
290
358
|
COMPONENTS.filter((c) => c !== "index").forEach((component) => {
|
|
291
359
|
console.log(chalk.cyan(` ${component}`));
|
|
292
|
-
console.log(chalk.dim(` ${
|
|
360
|
+
console.log(chalk.dim(` ${COMPONENT_DESCRIPTIONS[component]}
|
|
293
361
|
`));
|
|
294
362
|
});
|
|
295
363
|
console.log(chalk.dim("Install any component with: ") + chalk.white("npx zerozeeker add <component>"));
|