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.
- package/dist/index.js +147 -135
- 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(`
|
|
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
|
|
90
|
-
console.warn(chalk.yellow(`
|
|
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
|
-
|
|
103
|
-
|
|
104
|
-
|
|
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
|
|
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(`
|
|
223
|
+
console.log(chalk.green(` [+] ${check.name}`));
|
|
155
224
|
} else {
|
|
156
|
-
console.log(chalk.red(`
|
|
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
|
|
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
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
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
|
|
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(` ${
|
|
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>"));
|