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