zuro-cli 0.0.2-beta.0 → 0.0.2-beta.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/README.md ADDED
@@ -0,0 +1,40 @@
1
+ # zuro-cli
2
+
3
+ The backend builder for busy developers.
4
+
5
+ ## Usage
6
+
7
+ ```bash
8
+ npx zuro-cli@beta init
9
+ ```
10
+
11
+ Add modules:
12
+
13
+ ```bash
14
+ npx zuro-cli@beta add database
15
+ npx zuro-cli@beta add auth
16
+ ```
17
+
18
+ ## Docs
19
+
20
+ - https://zuro-cli.devbybriyan.com/docs
21
+
22
+ ## Registry
23
+
24
+ Default registry:
25
+
26
+ - https://registry.devbybriyan.com/channels/stable.json
27
+
28
+ Override for local testing:
29
+
30
+ ```bash
31
+ export ZURO_REGISTRY_URL=http://127.0.0.1:8787
32
+ ```
33
+
34
+ ## Development
35
+
36
+ ```bash
37
+ corepack pnpm install
38
+ corepack pnpm --filter zuro-cli build
39
+ corepack pnpm --filter zuro-cli lint
40
+ ```
package/dist/index.js CHANGED
@@ -35,7 +35,7 @@ var import_prompts = __toESM(require("prompts"));
35
35
 
36
36
  // src/utils/registry.ts
37
37
  var import_node_crypto = require("crypto");
38
- var DEFAULT_REGISTRY_BASE_URL = "https://zuro-cli.devbybriyan.com/registry";
38
+ var DEFAULT_REGISTRY_BASE_URL = "https://registry.devbybriyan.com";
39
39
  var DEFAULT_REGISTRY_ENTRY_URL = `${DEFAULT_REGISTRY_BASE_URL}/channels/stable.json`;
40
40
  var REGISTRY_ENV_VAR = "ZURO_REGISTRY_URL";
41
41
  var REQUEST_TIMEOUT_MS = 8e3;
@@ -189,15 +189,28 @@ async function fetchFile(filePath, options) {
189
189
  var import_fs_extra = __toESM(require("fs-extra"));
190
190
  var import_path = __toESM(require("path"));
191
191
  var import_execa = require("execa");
192
- async function initPackageJson(cwd, force = false) {
192
+ function normalizePackageName(name) {
193
+ const normalized = name.trim().toLowerCase().replace(/[^a-z0-9._-]/g, "-").replace(/-+/g, "-").replace(/^[._-]+|[._-]+$/g, "");
194
+ return normalized || "zuro-app";
195
+ }
196
+ async function ensurePackageManagerAvailable(pm) {
197
+ try {
198
+ await (0, import_execa.execa)(pm, ["--version"], { stdio: "ignore" });
199
+ } catch {
200
+ throw new Error(
201
+ `Package manager '${pm}' is not installed or not available in PATH. Install it or choose npm.`
202
+ );
203
+ }
204
+ }
205
+ async function initPackageJson(cwd, force = false, packageName = "zuro-app", srcDir = "src") {
193
206
  const pkgPath = import_path.default.join(cwd, "package.json");
194
207
  if (force || !await import_fs_extra.default.pathExists(pkgPath)) {
195
208
  await import_fs_extra.default.writeJson(pkgPath, {
196
- name: "zuro-app",
209
+ name: normalizePackageName(packageName),
197
210
  version: "0.0.1",
198
211
  private: true,
199
212
  scripts: {
200
- "dev": "tsx watch src/server.ts",
213
+ "dev": `tsx watch ${srcDir}/server.ts`,
201
214
  "build": "tsc",
202
215
  "start": "node dist/server.js"
203
216
  }
@@ -391,6 +404,21 @@ function resolveSafeTargetPath(projectRoot, srcDir, file) {
391
404
  targetPath
392
405
  };
393
406
  }
407
+ async function ensureSafeTargetDirectory(targetDir, cwd, projectName) {
408
+ await import_fs_extra4.default.ensureDir(targetDir);
409
+ const entries = await import_fs_extra4.default.readdir(targetDir);
410
+ if (entries.length === 0) {
411
+ return true;
412
+ }
413
+ const isCurrentFolder = targetDir === cwd;
414
+ const response = await (0, import_prompts.default)({
415
+ type: "confirm",
416
+ name: "proceed",
417
+ message: isCurrentFolder ? `Current folder '${projectName}' is not empty. Continue anyway?` : `Target folder '${projectName}' already exists and is not empty. Continue anyway?`,
418
+ initial: false
419
+ });
420
+ return response.proceed === true;
421
+ }
394
422
  async function init() {
395
423
  const cwd = process.cwd();
396
424
  const isExistingProject = await import_fs_extra4.default.pathExists(import_path4.default.join(cwd, "package.json"));
@@ -455,7 +483,11 @@ async function init() {
455
483
  } else {
456
484
  projectName = response.path.trim();
457
485
  targetDir = import_path4.default.resolve(cwd, projectName);
458
- await import_fs_extra4.default.ensureDir(targetDir);
486
+ }
487
+ const isSafeTarget = await ensureSafeTargetDirectory(targetDir, cwd, projectName);
488
+ if (!isSafeTarget) {
489
+ console.log(import_chalk2.default.red("Operation cancelled."));
490
+ return;
459
491
  }
460
492
  }
461
493
  const existingConfig = targetDir === cwd ? existingZuroConfig : await readZuroConfig(targetDir);
@@ -464,20 +496,26 @@ async function init() {
464
496
  pm,
465
497
  srcDir: srcDir || existingConfig?.srcDir || "src"
466
498
  };
467
- await writeZuroConfig(targetDir, zuroConfig);
468
499
  const spinner = (0, import_ora.default)("Connecting to Zuro Registry...").start();
500
+ let currentStep = "package manager preflight";
469
501
  try {
502
+ spinner.text = `Checking ${pm} availability...`;
503
+ await ensurePackageManagerAvailable(pm);
504
+ currentStep = "registry fetch";
505
+ spinner.text = "Connecting to Zuro Registry...";
470
506
  const registryContext = await fetchRegistry();
471
507
  const coreModule = registryContext.manifest.modules.core;
472
508
  if (!coreModule) {
473
509
  spinner.fail("Core module not found in registry.");
474
510
  return;
475
511
  }
512
+ currentStep = "project initialization";
476
513
  spinner.text = "Initializing project...";
477
514
  const hasPackageJson = await import_fs_extra4.default.pathExists(import_path4.default.join(targetDir, "package.json"));
478
515
  if (!hasPackageJson) {
479
- await initPackageJson(targetDir, true);
516
+ await initPackageJson(targetDir, true, projectName, srcDir);
480
517
  }
518
+ currentStep = "dependency installation";
481
519
  spinner.text = `Installing dependencies using ${pm}...`;
482
520
  let runtimeDeps = [];
483
521
  let devDeps = [];
@@ -492,6 +530,7 @@ async function init() {
492
530
  }
493
531
  await installDependencies(pm, runtimeDeps, targetDir);
494
532
  await installDependencies(pm, devDeps, targetDir, { dev: true });
533
+ currentStep = "module file generation";
495
534
  spinner.text = "Fetching core module files...";
496
535
  for (const file of coreModule.files) {
497
536
  const { relativeTargetPath, targetPath } = resolveSafeTargetPath(targetDir, srcDir, file);
@@ -514,7 +553,10 @@ async function init() {
514
553
  await import_fs_extra4.default.ensureDir(import_path4.default.dirname(targetPath));
515
554
  await import_fs_extra4.default.writeFile(targetPath, content);
516
555
  }
556
+ currentStep = "environment file setup";
517
557
  await createInitialEnv(targetDir);
558
+ currentStep = "config write";
559
+ await writeZuroConfig(targetDir, zuroConfig);
518
560
  spinner.succeed(import_chalk2.default.green("Project initialized successfully!"));
519
561
  console.log(`
520
562
  ${import_chalk2.default.bold("Next steps:")}`);
@@ -525,8 +567,15 @@ ${import_chalk2.default.bold("Next steps:")}`);
525
567
  console.log(`
526
568
  ${import_chalk2.default.dim("Add modules: zuro-cli add database, zuro-cli add auth")}`);
527
569
  } catch (error) {
528
- spinner.fail(import_chalk2.default.red("Failed to initialize project."));
529
- console.error(error);
570
+ spinner.fail(import_chalk2.default.red(`Failed during ${currentStep}.`));
571
+ const errorMessage = error instanceof Error ? error.message : String(error);
572
+ console.error(import_chalk2.default.red(errorMessage));
573
+ console.log(`
574
+ ${import_chalk2.default.bold("Retry:")}`);
575
+ if (targetDir !== cwd) {
576
+ console.log(import_chalk2.default.cyan(` cd ${projectName}`));
577
+ }
578
+ console.log(import_chalk2.default.cyan(" npx zuro-cli init"));
530
579
  }
531
580
  }
532
581
 
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/commands/init.ts","../src/utils/registry.ts","../src/utils/pm.ts","../src/utils/env-manager.ts","../src/utils/config.ts","../src/utils/project-guard.ts","../src/commands/add.ts","../src/utils/dependency.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from \"commander\";\nimport { init } from \"./commands/init\";\nimport { add } from \"./commands/add\";\n\nconst program = new Command();\n\nprogram\n .name(\"zuro-cli\")\n .description(\"Zuro CLI tool\")\n .version(\"0.0.1\");\n\nprogram\n .command(\"init\")\n .description(\"Initialize a new Zuro project\")\n .action(init);\n\nprogram\n .command(\"add <module>\")\n .description(\"Add a module to your project\")\n .action(add);\n\nprogram.parse(process.argv);\n","import ora from \"ora\";\nimport chalk from \"chalk\";\nimport fs from \"fs-extra\";\nimport path from \"path\";\nimport prompts from \"prompts\";\nimport { fetchRegistry, fetchFile, RegistryFile } from \"../utils/registry\";\nimport { initPackageJson, installDependencies } from \"../utils/pm\";\nimport { createInitialEnv } from \"../utils/env-manager\";\nimport { readZuroConfig, writeZuroConfig } from \"../utils/config\";\nimport { showNonZuroProjectMessage } from \"../utils/project-guard\";\nimport type { ZuroConfig } from \"../utils/config\";\n\nfunction resolveSafeTargetPath(projectRoot: string, srcDir: string, file: RegistryFile) {\n const relativeTargetPath = path.join(srcDir, file.target);\n const targetPath = path.resolve(projectRoot, relativeTargetPath);\n const normalizedRoot = path.resolve(projectRoot);\n\n if (targetPath !== normalizedRoot && !targetPath.startsWith(`${normalizedRoot}${path.sep}`)) {\n throw new Error(`Refusing to write outside project directory: ${file.target}`);\n }\n\n return {\n relativeTargetPath,\n targetPath,\n };\n}\n\nexport async function init() {\n const cwd = process.cwd();\n const isExistingProject = await fs.pathExists(path.join(cwd, \"package.json\"));\n const existingZuroConfig = await readZuroConfig(cwd);\n\n if (isExistingProject && !existingZuroConfig) {\n showNonZuroProjectMessage();\n return;\n }\n\n let targetDir = cwd;\n let pm = \"npm\";\n let srcDir = \"src\";\n let projectName = path.basename(cwd);\n\n if (isExistingProject) {\n console.log(chalk.blue(\"ℹ Existing project detected.\"));\n\n projectName = path.basename(cwd);\n\n if (await fs.pathExists(path.join(cwd, \"pnpm-lock.yaml\"))) {\n pm = \"pnpm\";\n } else if (await fs.pathExists(path.join(cwd, \"bun.lockb\"))) {\n pm = \"bun\";\n } else if (await fs.pathExists(path.join(cwd, \"yarn.lock\"))) {\n pm = \"yarn\";\n }\n\n const response = await prompts({\n type: \"text\",\n name: \"srcDir\",\n message: \"Where is your source code located?\",\n initial: \"src\",\n });\n\n srcDir = response.srcDir || \"src\";\n } else {\n console.log(chalk.dim(` Tip: Leave blank to use current folder (${path.basename(cwd)})\\n`));\n\n const response = await prompts([\n {\n type: \"text\",\n name: \"path\",\n message: \"Project name (blank for current folder)\",\n initial: \"\",\n },\n {\n type: \"select\",\n name: \"pm\",\n message: \"Package Manager?\",\n choices: [\n { title: \"npm\", value: \"npm\" },\n { title: \"pnpm\", value: \"pnpm\" },\n { title: \"bun\", value: \"bun\" },\n ],\n initial: 0,\n },\n ]);\n\n if (response.pm === undefined) {\n console.log(chalk.red(\"Operation cancelled.\"));\n return;\n }\n\n pm = response.pm;\n srcDir = \"src\";\n\n if (!response.path || response.path.trim() === \"\") {\n projectName = path.basename(cwd);\n targetDir = cwd;\n console.log(chalk.blue(`ℹ Using current folder: ${projectName}`));\n } else {\n projectName = response.path.trim();\n targetDir = path.resolve(cwd, projectName);\n await fs.ensureDir(targetDir);\n }\n }\n\n const existingConfig = targetDir === cwd ? existingZuroConfig : await readZuroConfig(targetDir);\n\n const zuroConfig: ZuroConfig = {\n name: projectName,\n pm,\n srcDir: srcDir || existingConfig?.srcDir || \"src\",\n };\n\n await writeZuroConfig(targetDir, zuroConfig);\n\n const spinner = ora(\"Connecting to Zuro Registry...\").start();\n\n try {\n const registryContext = await fetchRegistry();\n\n const coreModule = registryContext.manifest.modules.core;\n\n if (!coreModule) {\n spinner.fail(\"Core module not found in registry.\");\n return;\n }\n\n spinner.text = \"Initializing project...\";\n\n const hasPackageJson = await fs.pathExists(path.join(targetDir, \"package.json\"));\n if (!hasPackageJson) {\n await initPackageJson(targetDir, true);\n }\n\n spinner.text = `Installing dependencies using ${pm}...`;\n\n let runtimeDeps: string[] = [];\n let devDeps: string[] = [];\n\n if (isExistingProject) {\n const safeDeps = [\"zod\", \"dotenv\"];\n const coreDeps = coreModule.dependencies || [];\n runtimeDeps = coreDeps.filter((dependency) => safeDeps.includes(dependency));\n devDeps = coreModule.devDependencies || [];\n } else {\n runtimeDeps = coreModule.dependencies || [];\n devDeps = coreModule.devDependencies || [];\n }\n\n await installDependencies(pm, runtimeDeps, targetDir);\n await installDependencies(pm, devDeps, targetDir, { dev: true });\n\n spinner.text = \"Fetching core module files...\";\n\n for (const file of coreModule.files) {\n const { relativeTargetPath, targetPath } = resolveSafeTargetPath(targetDir, srcDir, file);\n const fileName = path.basename(targetPath);\n\n if (isExistingProject) {\n if (fileName === \"app.ts\" || fileName === \"server.ts\") {\n continue;\n }\n\n const relativeParts = relativeTargetPath.split(path.sep);\n const isSafe = fileName === \"env.ts\" || relativeParts.includes(\"lib\");\n if (!isSafe) {\n continue;\n }\n }\n\n const content = await fetchFile(file.path, {\n baseUrl: registryContext.fileBaseUrl,\n expectedSha256: file.sha256,\n expectedSize: file.size,\n });\n\n await fs.ensureDir(path.dirname(targetPath));\n await fs.writeFile(targetPath, content);\n }\n\n await createInitialEnv(targetDir);\n\n spinner.succeed(chalk.green(\"Project initialized successfully!\"));\n\n console.log(`\\n${chalk.bold(\"Next steps:\")}`);\n if (targetDir !== cwd) {\n console.log(chalk.cyan(` cd ${projectName}`));\n }\n console.log(chalk.cyan(` ${pm} run dev`));\n console.log(`\\n${chalk.dim(\"Add modules: zuro-cli add database, zuro-cli add auth\")}`);\n } catch (error) {\n spinner.fail(chalk.red(\"Failed to initialize project.\"));\n console.error(error);\n }\n}\n","import { createHash } from \"node:crypto\";\n\nconst DEFAULT_REGISTRY_BASE_URL = \"https://zuro-cli.devbybriyan.com/registry\";\nconst DEFAULT_REGISTRY_ENTRY_URL = `${DEFAULT_REGISTRY_BASE_URL}/channels/stable.json`;\nconst REGISTRY_ENV_VAR = \"ZURO_REGISTRY_URL\";\nconst REQUEST_TIMEOUT_MS = 8000;\nconst MAX_RETRIES = 2;\n\nexport interface RegistryFile {\n path: string;\n target: string;\n type: string;\n sha256?: string;\n size?: number;\n}\n\nexport interface RegistryModule {\n type: string;\n files: RegistryFile[];\n moduleDependencies?: string[];\n dependencies?: string[];\n devDependencies?: string[];\n}\n\nexport interface RegistryManifest {\n schemaVersion?: number;\n status?: string;\n templateVersion?: string;\n generatedAt?: string;\n modules: Record<string, RegistryModule>;\n}\n\ninterface RegistryChannelPointer {\n schemaVersion?: number;\n channel?: string;\n templateVersion?: string;\n generatedAt?: string;\n indexPath?: string;\n indexUrl?: string;\n}\n\nexport interface RegistryContext {\n manifest: RegistryManifest;\n manifestUrl: string;\n fileBaseUrl: string;\n}\n\ninterface FetchFileOptions {\n baseUrl: string;\n expectedSha256?: string;\n expectedSize?: number;\n}\n\nexport function getRegistryUrl() {\n return resolveRegistryEntryUrl();\n}\n\nfunction withTrailingSlash(url: string) {\n return url.endsWith(\"/\") ? url : `${url}/`;\n}\n\nfunction resolveRegistryEntryUrl() {\n const override = process.env[REGISTRY_ENV_VAR]?.trim();\n\n if (!override) {\n return DEFAULT_REGISTRY_ENTRY_URL;\n }\n\n let parsed: URL;\n\n try {\n parsed = new URL(override);\n } catch {\n throw new Error(\n `Invalid ${REGISTRY_ENV_VAR} value '${override}'. Expected a valid http(s) URL.`\n );\n }\n\n if (parsed.pathname.endsWith(\".json\")) {\n return parsed.toString();\n }\n\n return new URL(\"channels/stable.json\", withTrailingSlash(parsed.toString())).toString();\n}\n\nfunction isRegistryManifest(data: unknown): data is RegistryManifest {\n if (!data || typeof data !== \"object\") {\n return false;\n }\n\n const candidate = data as Partial<RegistryManifest>;\n return !!candidate.modules && typeof candidate.modules === \"object\";\n}\n\nfunction isChannelPointer(data: unknown): data is RegistryChannelPointer {\n if (!data || typeof data !== \"object\") {\n return false;\n }\n\n const candidate = data as Partial<RegistryChannelPointer>;\n return typeof candidate.indexPath === \"string\" || typeof candidate.indexUrl === \"string\";\n}\n\nfunction delay(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nasync function fetchWithRetry(url: string): Promise<Response> {\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);\n\n try {\n const response = await fetch(url, {\n headers: { Accept: \"application/json, text/plain, */*\" },\n signal: controller.signal,\n });\n\n if (response.ok) {\n return response;\n }\n\n const shouldRetry = response.status >= 500 && attempt < MAX_RETRIES;\n if (shouldRetry) {\n await delay(250 * (attempt + 1));\n continue;\n }\n\n throw new Error(`Request failed (${response.status} ${response.statusText}) for ${url}`);\n } catch (error) {\n lastError = error;\n\n if (attempt === MAX_RETRIES) {\n break;\n }\n\n await delay(250 * (attempt + 1));\n } finally {\n clearTimeout(timeout);\n }\n }\n\n if (lastError instanceof Error) {\n throw lastError;\n }\n\n throw new Error(`Failed to fetch ${url}`);\n}\n\nasync function fetchJson<T>(url: string): Promise<{ data: T; resolvedUrl: string }> {\n const response = await fetchWithRetry(url);\n const data = (await response.json()) as T;\n\n return {\n data,\n resolvedUrl: response.url || url,\n };\n}\n\nfunction resolveManifestUrl(pointer: RegistryChannelPointer, pointerUrl: string): string {\n const explicit = pointer.indexUrl || pointer.indexPath;\n\n if (!explicit) {\n throw new Error(\"Registry channel pointer is missing indexUrl/indexPath\");\n }\n\n return new URL(explicit, pointerUrl).toString();\n}\n\nexport async function fetchRegistry(): Promise<RegistryContext> {\n const registryEntryUrl = resolveRegistryEntryUrl();\n let entry: { data: unknown; resolvedUrl: string };\n\n try {\n entry = await fetchJson<unknown>(registryEntryUrl);\n } catch (error) {\n throw new Error(\n `Unable to fetch registry from ${registryEntryUrl}. For local testing set ${REGISTRY_ENV_VAR}=http://127.0.0.1:8787.`,\n { cause: error as Error }\n );\n }\n\n if (isRegistryManifest(entry.data)) {\n return {\n manifest: entry.data,\n manifestUrl: entry.resolvedUrl,\n fileBaseUrl: withTrailingSlash(new URL(\".\", entry.resolvedUrl).toString()),\n };\n }\n\n if (!isChannelPointer(entry.data)) {\n throw new Error(\n `Invalid registry payload at ${registryEntryUrl}. Expected manifest or channel pointer.`\n );\n }\n\n const manifestUrl = resolveManifestUrl(entry.data, entry.resolvedUrl);\n const manifestResult = await fetchJson<unknown>(manifestUrl);\n\n if (!isRegistryManifest(manifestResult.data)) {\n throw new Error(`Invalid manifest payload at ${manifestUrl}.`);\n }\n\n return {\n manifest: manifestResult.data,\n manifestUrl: manifestResult.resolvedUrl,\n fileBaseUrl: withTrailingSlash(new URL(\".\", manifestResult.resolvedUrl).toString()),\n };\n}\n\nexport async function fetchFile(filePath: string, options: FetchFileOptions) {\n const normalizedPath = filePath.replace(/^\\//, \"\");\n const fileUrl = new URL(normalizedPath, withTrailingSlash(options.baseUrl)).toString();\n const response = await fetchWithRetry(fileUrl);\n const content = await response.text();\n\n if (typeof options.expectedSize === \"number\") {\n const actualSize = Buffer.byteLength(content, \"utf8\");\n if (actualSize !== options.expectedSize) {\n throw new Error(\n `Size mismatch for ${filePath}. Expected ${options.expectedSize}, got ${actualSize}.`\n );\n }\n }\n\n if (options.expectedSha256) {\n const actualSha256 = createHash(\"sha256\").update(content, \"utf8\").digest(\"hex\");\n if (actualSha256 !== options.expectedSha256) {\n throw new Error(\n `Checksum mismatch for ${filePath}. Expected ${options.expectedSha256}, got ${actualSha256}.`\n );\n }\n }\n\n return content;\n}\n","import fs from \"fs-extra\";\nimport path from \"path\";\nimport { execa } from \"execa\";\n\nexport async function initPackageJson(cwd: string, force: boolean = false) {\n const pkgPath = path.join(cwd, \"package.json\");\n if (force || !await fs.pathExists(pkgPath)) {\n await fs.writeJson(pkgPath, {\n name: \"zuro-app\",\n version: \"0.0.1\",\n private: true,\n scripts: {\n \"dev\": \"tsx watch src/server.ts\",\n \"build\": \"tsc\",\n \"start\": \"node dist/server.js\"\n }\n }, { spaces: 2 });\n }\n}\n\ninterface InstallOptions {\n dev?: boolean;\n}\n\nexport async function installDependencies(\n pm: string,\n deps: string[],\n cwd: string,\n options: InstallOptions = {}\n) {\n const uniqueDeps = [...new Set(deps)].filter(Boolean);\n\n if (uniqueDeps.length === 0) {\n return;\n }\n\n const isDev = options.dev ?? false;\n\n if (pm === \"npm\") {\n const args = [\"install\", ...(isDev ? [\"--save-dev\"] : []), ...uniqueDeps];\n await execa(\"npm\", args, { cwd });\n return;\n }\n\n if (pm === \"pnpm\") {\n const args = [\"add\", ...(isDev ? [\"-D\"] : []), ...uniqueDeps];\n await execa(\"pnpm\", args, { cwd });\n return;\n }\n\n if (pm === \"yarn\") {\n const args = [\"add\", ...(isDev ? [\"-D\"] : []), ...uniqueDeps];\n await execa(\"yarn\", args, { cwd });\n return;\n }\n\n if (pm === \"bun\") {\n const args = [\"add\", ...(isDev ? [\"-d\"] : []), ...uniqueDeps];\n await execa(\"bun\", args, { cwd });\n return;\n }\n\n throw new Error(`Unsupported package manager: ${pm}`);\n}\n","import fs from \"fs-extra\";\r\nimport path from \"path\";\r\nimport os from \"os\";\r\n\r\n/**\r\n * Creates or updates .env file with new variables\r\n */\r\nexport const updateEnvFile = async (\r\n cwd: string,\r\n variables: Record<string, string>,\r\n createIfMissing = true\r\n) => {\r\n const envPath = path.join(cwd, \".env\");\r\n\r\n let content = \"\";\r\n if (fs.existsSync(envPath)) {\r\n content = await fs.readFile(envPath, \"utf-8\");\r\n } else if (!createIfMissing) {\r\n return;\r\n }\r\n\r\n let modified = false;\r\n\r\n for (const [key, value] of Object.entries(variables)) {\r\n // Check if key already exists\r\n const regex = new RegExp(`^${key}=`, \"m\");\r\n if (!regex.test(content)) {\r\n // Add newline if content doesn't end with one\r\n if (content && !content.endsWith(\"\\n\")) {\r\n content += os.EOL;\r\n }\r\n content += `${key}=${value}${os.EOL}`;\r\n modified = true;\r\n }\r\n }\r\n\r\n if (modified || !fs.existsSync(envPath)) {\r\n await fs.writeFile(envPath, content);\r\n }\r\n};\r\n\r\n/**\r\n * Updates env.ts to add new schema fields\r\n */\r\nexport const updateEnvSchema = async (\r\n cwd: string,\r\n srcDir: string,\r\n fields: Array<{ name: string; schema: string }>\r\n) => {\r\n const envPath = path.join(cwd, srcDir, \"env.ts\");\r\n\r\n if (!fs.existsSync(envPath)) {\r\n return false;\r\n }\r\n\r\n let content = await fs.readFile(envPath, \"utf-8\");\r\n let modified = false;\r\n\r\n for (const field of fields) {\r\n // Check if field already exists in schema\r\n if (content.includes(`${field.name}:`)) {\r\n continue;\r\n }\r\n\r\n // Find the closing of envSchema z.object({ ... })\r\n // Insert before the closing });\r\n const schemaEndRegex = /(\\n\\s*)(}\\);?\\s*\\n\\s*export const env)/;\r\n const match = content.match(schemaEndRegex);\r\n\r\n if (match) {\r\n const indent = \" \"; // 4 spaces\r\n const newField = `${indent}${field.name}: ${field.schema},\\n`;\r\n content = content.replace(\r\n schemaEndRegex,\r\n `\\n${newField}$1$2`\r\n );\r\n modified = true;\r\n }\r\n }\r\n\r\n if (modified) {\r\n await fs.writeFile(envPath, content);\r\n }\r\n\r\n return modified;\r\n};\r\n\r\n/**\r\n * Creates initial .env file for new projects\r\n */\r\nexport const createInitialEnv = async (cwd: string) => {\r\n const envPath = path.join(cwd, \".env\");\r\n\r\n if (fs.existsSync(envPath)) {\r\n return; // Don't overwrite existing\r\n }\r\n\r\n const content = `# Environment Variables\r\nPORT=3000\r\nNODE_ENV=development\r\n`;\r\n\r\n await fs.writeFile(envPath, content);\r\n};\r\n\r\n/**\r\n * Module-specific env configurations\r\n */\r\nexport const ENV_CONFIGS = {\r\n \"database-pg\": {\r\n envVars: {\r\n DATABASE_URL: \"postgresql://postgres@localhost:5432/mydb\",\r\n },\r\n schemaFields: [\r\n { name: \"DATABASE_URL\", schema: \"z.string().url()\" },\r\n ],\r\n },\r\n \"database-mysql\": {\r\n envVars: {\r\n DATABASE_URL: \"mysql://root@localhost:3306/mydb\",\r\n },\r\n schemaFields: [\r\n { name: \"DATABASE_URL\", schema: \"z.string().url()\" },\r\n ],\r\n },\r\n auth: {\r\n envVars: {\r\n BETTER_AUTH_SECRET: \"your-secret-key-at-least-32-characters-long\",\r\n BETTER_AUTH_URL: \"http://localhost:3000\",\r\n },\r\n schemaFields: [\r\n { name: \"BETTER_AUTH_SECRET\", schema: \"z.string().min(32)\" },\r\n { name: \"BETTER_AUTH_URL\", schema: \"z.string().url()\" },\r\n ],\r\n },\r\n};\r\n","import fs from \"fs-extra\";\nimport path from \"path\";\n\nexport interface ZuroConfig {\n name?: string;\n pm?: string;\n srcDir?: string;\n}\n\nfunction sanitizeConfig(input: unknown): ZuroConfig {\n if (!input || typeof input !== \"object\") {\n return {};\n }\n\n const raw = input as Record<string, unknown>;\n const config: ZuroConfig = {};\n\n if (typeof raw.name === \"string\") {\n config.name = raw.name;\n }\n\n if (typeof raw.pm === \"string\") {\n config.pm = raw.pm;\n }\n\n if (typeof raw.srcDir === \"string\") {\n config.srcDir = raw.srcDir;\n }\n\n return config;\n}\n\nexport function getConfigPath(cwd: string) {\n return path.join(cwd, \"zuro.json\");\n}\n\nexport async function readZuroConfig(cwd: string): Promise<ZuroConfig | null> {\n const configPath = getConfigPath(cwd);\n\n if (!(await fs.pathExists(configPath))) {\n return null;\n }\n\n const raw = await fs.readJson(configPath);\n return sanitizeConfig(raw);\n}\n\nexport async function writeZuroConfig(cwd: string, config: ZuroConfig) {\n const configPath = getConfigPath(cwd);\n await fs.writeJson(configPath, sanitizeConfig(config), { spaces: 2 });\n}\n","import chalk from \"chalk\";\n\nexport function showNonZuroProjectMessage() {\n console.log(chalk.yellow(\"This directory looks like an existing project that wasn't created with Zuro CLI.\"));\n console.log(\"\");\n console.log(chalk.yellow(\"We stopped here because we don't want to make unnecessary changes to your project.\"));\n console.log(\"\");\n console.log(\"Zuro CLI works in:\");\n console.log(\"- a fresh/empty directory, or\");\n console.log(\"- an existing project already managed by Zuro CLI.\");\n}\n","import prompts from \"prompts\";\nimport ora from \"ora\";\nimport path from \"path\";\nimport fs from \"fs-extra\";\nimport { fetchRegistry, fetchFile, RegistryFile } from \"../utils/registry\";\nimport { installDependencies } from \"../utils/pm\";\nimport { resolveDependencies } from \"../utils/dependency\";\nimport { updateEnvFile, updateEnvSchema, ENV_CONFIGS } from \"../utils/env-manager\";\nimport chalk from \"chalk\";\nimport { readZuroConfig } from \"../utils/config\";\nimport { showNonZuroProjectMessage } from \"../utils/project-guard\";\n\nfunction resolveSafeTargetPath(projectRoot: string, srcDir: string, file: RegistryFile) {\n const targetPath = path.resolve(projectRoot, srcDir, file.target);\n const normalizedRoot = path.resolve(projectRoot);\n\n if (targetPath !== normalizedRoot && !targetPath.startsWith(`${normalizedRoot}${path.sep}`)) {\n throw new Error(`Refusing to write outside project directory: ${file.target}`);\n }\n\n return targetPath;\n}\n\n/**\n * Modifies app.ts to include error handler middleware\n */\nasync function injectErrorHandler(projectRoot: string, srcDir: string): Promise<boolean> {\n const appPath = path.join(projectRoot, srcDir, \"app.ts\");\n\n if (!fs.existsSync(appPath)) {\n return false;\n }\n\n let content = await fs.readFile(appPath, \"utf-8\");\n\n if (content.includes(\"errorHandler\")) {\n return true;\n }\n\n const errorImport = `import { errorHandler, notFoundHandler } from \"./middleware/error-handler\";`;\n\n const importRegex = /^import .+ from .+;?\\s*$/gm;\n let lastImportIndex = 0;\n let match;\n\n while ((match = importRegex.exec(content)) !== null) {\n lastImportIndex = match.index + match[0].length;\n }\n\n if (lastImportIndex > 0) {\n content = content.slice(0, lastImportIndex) + `\\n${errorImport}` + content.slice(lastImportIndex);\n }\n\n const errorSetup = `\\n// Error handling (must be last)\\napp.use(notFoundHandler);\\napp.use(errorHandler);\\n`;\n const exportMatch = content.match(/export default app;?\\s*$/m);\n if (exportMatch && exportMatch.index !== undefined) {\n content = content.slice(0, exportMatch.index) + errorSetup + \"\\n\" + content.slice(exportMatch.index);\n }\n\n await fs.writeFile(appPath, content);\n return true;\n}\n\n/**\n * Modifies app.ts to include auth routes\n */\nasync function injectAuthRoutes(projectRoot: string, srcDir: string): Promise<boolean> {\n const appPath = path.join(projectRoot, srcDir, \"app.ts\");\n\n if (!fs.existsSync(appPath)) {\n return false;\n }\n\n let content = await fs.readFile(appPath, \"utf-8\");\n\n if (content.includes(\"routes/auth.routes\")) {\n return true;\n }\n\n const authImport = `import authRoutes from \"./routes/auth.routes\";`;\n const userImport = `import userRoutes from \"./routes/user.routes\";`;\n const routeSetup = `\\n// Auth routes\\napp.use(authRoutes);\\napp.use(\"/api/users\", userRoutes);\\n`;\n\n const importRegex = /^import .+ from .+;?\\s*$/gm;\n let lastImportIndex = 0;\n let match;\n\n while ((match = importRegex.exec(content)) !== null) {\n lastImportIndex = match.index + match[0].length;\n }\n\n if (lastImportIndex > 0) {\n content = content.slice(0, lastImportIndex) + `\\n${authImport}\\n${userImport}` + content.slice(lastImportIndex);\n }\n\n const exportMatch = content.match(/export default app;?\\s*$/m);\n if (exportMatch && exportMatch.index !== undefined) {\n content = content.slice(0, exportMatch.index) + routeSetup + \"\\n\" + content.slice(exportMatch.index);\n }\n\n await fs.writeFile(appPath, content);\n return true;\n}\n\nexport const add = async (moduleName: string) => {\n const projectRoot = process.cwd();\n const projectConfig = await readZuroConfig(projectRoot);\n if (!projectConfig) {\n showNonZuroProjectMessage();\n return;\n }\n let srcDir = projectConfig.srcDir || \"src\";\n\n let customDbUrl: string | undefined;\n\n const DEFAULT_URLS = {\n \"database-pg\": \"postgresql://root@localhost:5432/mydb\",\n \"database-mysql\": \"mysql://root@localhost:3306/mydb\",\n };\n\n if (moduleName === \"database\") {\n const variantResponse = await prompts({\n type: \"select\",\n name: \"variant\",\n message: \"Which database dialect?\",\n choices: [\n { title: \"PostgreSQL\", value: \"database-pg\" },\n { title: \"MySQL\", value: \"database-mysql\" },\n ],\n });\n\n if (!variantResponse.variant) {\n process.exit(0);\n }\n\n moduleName = variantResponse.variant;\n\n const defaultUrl = DEFAULT_URLS[moduleName as keyof typeof DEFAULT_URLS];\n console.log(chalk.dim(` Tip: Leave blank to use ${defaultUrl}\\n`));\n\n const urlResponse = await prompts({\n type: \"text\",\n name: \"dbUrl\",\n message: \"Database URL\",\n initial: \"\",\n });\n customDbUrl = urlResponse.dbUrl?.trim() || defaultUrl;\n }\n\n if ((moduleName === \"database-pg\" || moduleName === \"database-mysql\") && customDbUrl === undefined) {\n const defaultUrl = DEFAULT_URLS[moduleName as keyof typeof DEFAULT_URLS];\n console.log(chalk.dim(` Tip: Leave blank to use ${defaultUrl}\\n`));\n\n const response = await prompts({\n type: \"text\",\n name: \"dbUrl\",\n message: \"Database URL\",\n initial: \"\",\n });\n customDbUrl = response.dbUrl?.trim() || defaultUrl;\n }\n\n const spinner = ora(`Checking registry for ${moduleName}...`).start();\n\n try {\n const registryContext = await fetchRegistry();\n const module = registryContext.manifest.modules[moduleName];\n\n if (!module) {\n spinner.fail(`Module '${moduleName}' not found.`);\n return;\n }\n\n spinner.succeed(`Found module: ${chalk.cyan(moduleName)}`);\n\n const moduleDeps = module.moduleDependencies || [];\n await resolveDependencies(moduleDeps, projectRoot);\n\n spinner.start(\"Installing dependencies...\");\n\n let pm = \"npm\";\n if (fs.existsSync(path.join(projectRoot, \"pnpm-lock.yaml\"))) {\n pm = \"pnpm\";\n } else if (fs.existsSync(path.join(projectRoot, \"bun.lockb\"))) {\n pm = \"bun\";\n } else if (fs.existsSync(path.join(projectRoot, \"yarn.lock\"))) {\n pm = \"yarn\";\n }\n\n await installDependencies(pm, module.dependencies || [], projectRoot);\n await installDependencies(pm, module.devDependencies || [], projectRoot, { dev: true });\n\n spinner.succeed(\"Dependencies installed\");\n\n spinner.start(\"Scaffolding files...\");\n\n for (const file of module.files) {\n const content = await fetchFile(file.path, {\n baseUrl: registryContext.fileBaseUrl,\n expectedSha256: file.sha256,\n expectedSize: file.size,\n });\n\n const targetPath = resolveSafeTargetPath(projectRoot, srcDir, file);\n\n await fs.ensureDir(path.dirname(targetPath));\n await fs.writeFile(targetPath, content);\n }\n\n spinner.succeed(\"Files generated\");\n\n if (moduleName === \"auth\") {\n spinner.start(\"Configuring routes in app.ts...\");\n const injected = await injectAuthRoutes(projectRoot, srcDir);\n if (injected) {\n spinner.succeed(\"Routes configured in app.ts\");\n } else {\n spinner.warn(\"Could not find app.ts - routes need manual setup\");\n }\n }\n\n if (moduleName === \"error-handler\") {\n spinner.start(\"Configuring error handler in app.ts...\");\n const injected = await injectErrorHandler(projectRoot, srcDir);\n if (injected) {\n spinner.succeed(\"Error handler configured in app.ts\");\n } else {\n spinner.warn(\"Could not find app.ts - error handler needs manual setup\");\n }\n }\n\n const envConfig = ENV_CONFIGS[moduleName as keyof typeof ENV_CONFIGS];\n if (envConfig) {\n spinner.start(\"Updating environment configuration...\");\n\n const envVars: Record<string, string> = { ...envConfig.envVars };\n if (customDbUrl && (moduleName === \"database-pg\" || moduleName === \"database-mysql\")) {\n envVars.DATABASE_URL = customDbUrl;\n }\n\n await updateEnvFile(projectRoot, envVars);\n await updateEnvSchema(projectRoot, srcDir, envConfig.schemaFields);\n\n spinner.succeed(\"Environment configured\");\n }\n\n console.log(chalk.green(`\\n✔ ${moduleName} added successfully!\\n`));\n\n if (moduleName === \"auth\") {\n console.log(chalk.bold(\"📋 Next Steps:\\n\"));\n console.log(chalk.yellow(\"1. Update your .env file:\"));\n console.log(\n chalk.dim(\" We added placeholder values. Update BETTER_AUTH_SECRET with a secure key.\\n\")\n );\n console.log(chalk.yellow(\"2. Run database migrations:\"));\n console.log(chalk.cyan(\" npx drizzle-kit generate\"));\n console.log(chalk.cyan(\" npx drizzle-kit migrate\\n\"));\n console.log(chalk.yellow(\"3. Available endpoints:\"));\n console.log(chalk.dim(\" POST /auth/sign-up/email - Register\"));\n console.log(chalk.dim(\" POST /auth/sign-in/email - Login\"));\n console.log(chalk.dim(\" POST /auth/sign-out - Logout\"));\n console.log(chalk.dim(\" GET /api/users/me - Current user\\n\"));\n } else if (moduleName === \"error-handler\") {\n console.log(chalk.bold(\"📋 Usage:\\n\"));\n console.log(chalk.yellow(\"Throw errors in your controllers:\"));\n console.log(chalk.dim(\" ─────────────────────────────────────\"));\n console.log(chalk.white(` import { UnauthorizedError, NotFoundError } from \"./lib/errors\";`));\n console.log(\"\");\n console.log(chalk.white(` throw new UnauthorizedError(\"Invalid credentials\");`));\n console.log(chalk.white(` throw new NotFoundError(\"User not found\");`));\n console.log(chalk.dim(\" ─────────────────────────────────────\\n\"));\n console.log(chalk.yellow(\"Available error classes:\"));\n console.log(chalk.dim(\" BadRequestError (400)\"));\n console.log(chalk.dim(\" UnauthorizedError (401)\"));\n console.log(chalk.dim(\" ForbiddenError (403)\"));\n console.log(chalk.dim(\" NotFoundError (404)\"));\n console.log(chalk.dim(\" ConflictError (409)\"));\n console.log(chalk.dim(\" ValidationError (422)\"));\n console.log(chalk.dim(\" InternalServerError (500)\\n\"));\n console.log(chalk.yellow(\"Wrap async handlers:\"));\n console.log(chalk.dim(\" ─────────────────────────────────────\"));\n console.log(chalk.white(` import { asyncHandler } from \"./middleware/error-handler\";`));\n console.log(\"\");\n console.log(chalk.white(` router.get(\"/users\", asyncHandler(async (req, res) => {`));\n console.log(chalk.white(\" // errors auto-caught\"));\n console.log(chalk.white(\" }));\"));\n console.log(chalk.dim(\" ─────────────────────────────────────\\n\"));\n } else if (moduleName.includes(\"database\")) {\n console.log(chalk.bold(\"📋 Next Steps:\\n\"));\n let stepNum = 1;\n\n if (!customDbUrl) {\n console.log(chalk.yellow(`${stepNum}. Update DATABASE_URL in .env:`));\n console.log(\n chalk.dim(\" We added a placeholder. Update with your actual database credentials.\\n\")\n );\n stepNum++;\n }\n\n console.log(chalk.yellow(`${stepNum}. Create schemas in src/db/schema/:`));\n console.log(chalk.dim(\" Add table files and export from index.ts\\n\"));\n stepNum++;\n\n console.log(chalk.yellow(`${stepNum}. Run migrations:`));\n console.log(chalk.cyan(\" npx drizzle-kit generate\"));\n console.log(chalk.cyan(\" npx drizzle-kit migrate\\n\"));\n }\n } catch (error) {\n spinner.fail(`Failed to add module: ${(error as Error).message}`);\n }\n};\n","import { add } from \"../commands/add\";\nimport { readZuroConfig } from \"./config\";\nimport fs from \"fs-extra\";\nimport path from \"path\";\nimport chalk from \"chalk\";\n\n// Signature files to check if a Zuro module is installed\nconst BLOCK_SIGNATURES: Record<string, string> = {\n core: \"env.ts\",\n \"database-pg\": \"db/index.ts\",\n \"database-mysql\": \"db/index.ts\",\n validator: \"middleware/validate.ts\",\n \"error-handler\": \"lib/errors.ts\",\n logger: \"lib/logger.ts\",\n auth: \"lib/auth.ts\",\n};\n\n/**\n * Resolves Zuro module dependencies (NOT npm packages).\n * Only handles module dependencies like \"core\", \"database\", \"validator\", \"auth\".\n */\nexport const resolveDependencies = async (\n moduleDependencies: string[] | undefined,\n cwd: string\n) => {\n if (!moduleDependencies || moduleDependencies.length === 0) {\n return;\n }\n\n const config = await readZuroConfig(cwd);\n const srcDir = config?.srcDir || \"src\";\n\n for (const dep of moduleDependencies) {\n if (dep === \"database\") {\n const pgExists = fs.existsSync(path.join(cwd, srcDir, BLOCK_SIGNATURES[\"database-pg\"]));\n const mysqlExists = fs.existsSync(path.join(cwd, srcDir, BLOCK_SIGNATURES[\"database-mysql\"]));\n\n if (pgExists || mysqlExists) {\n continue;\n }\n\n console.log(chalk.blue(`ℹ Dependency '${dep}' is missing. Triggering install...`));\n await add(\"database\");\n continue;\n }\n\n const signature = BLOCK_SIGNATURES[dep];\n if (!signature) {\n continue;\n }\n\n if (fs.existsSync(path.join(cwd, srcDir, signature))) {\n continue;\n }\n\n console.log(chalk.blue(`ℹ Installing missing dependency: ${dep}...`));\n await add(dep);\n }\n};\n"],"mappings":"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","names":["import_chalk","import_fs_extra","import_path","path","fs","import_fs_extra","import_path","path","fs","os","import_fs_extra","import_path","path","fs","chalk","path","fs","chalk","prompts","ora","import_prompts","import_ora","import_path","import_fs_extra","import_fs_extra","import_path","import_chalk","fs","path","chalk","import_chalk","resolveSafeTargetPath","path","fs","prompts","chalk","ora","module"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/commands/init.ts","../src/utils/registry.ts","../src/utils/pm.ts","../src/utils/env-manager.ts","../src/utils/config.ts","../src/utils/project-guard.ts","../src/commands/add.ts","../src/utils/dependency.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from \"commander\";\nimport { init } from \"./commands/init\";\nimport { add } from \"./commands/add\";\n\nconst program = new Command();\n\nprogram\n .name(\"zuro-cli\")\n .description(\"Zuro CLI tool\")\n .version(\"0.0.1\");\n\nprogram\n .command(\"init\")\n .description(\"Initialize a new Zuro project\")\n .action(init);\n\nprogram\n .command(\"add <module>\")\n .description(\"Add a module to your project\")\n .action(add);\n\nprogram.parse(process.argv);\n","import ora from \"ora\";\nimport chalk from \"chalk\";\nimport fs from \"fs-extra\";\nimport path from \"path\";\nimport prompts from \"prompts\";\nimport { fetchRegistry, fetchFile, RegistryFile } from \"../utils/registry\";\nimport { initPackageJson, installDependencies, ensurePackageManagerAvailable } from \"../utils/pm\";\nimport { createInitialEnv } from \"../utils/env-manager\";\nimport { readZuroConfig, writeZuroConfig } from \"../utils/config\";\nimport { showNonZuroProjectMessage } from \"../utils/project-guard\";\nimport type { ZuroConfig } from \"../utils/config\";\n\nfunction resolveSafeTargetPath(projectRoot: string, srcDir: string, file: RegistryFile) {\n const relativeTargetPath = path.join(srcDir, file.target);\n const targetPath = path.resolve(projectRoot, relativeTargetPath);\n const normalizedRoot = path.resolve(projectRoot);\n\n if (targetPath !== normalizedRoot && !targetPath.startsWith(`${normalizedRoot}${path.sep}`)) {\n throw new Error(`Refusing to write outside project directory: ${file.target}`);\n }\n\n return {\n relativeTargetPath,\n targetPath,\n };\n}\n\nasync function ensureSafeTargetDirectory(targetDir: string, cwd: string, projectName: string) {\n await fs.ensureDir(targetDir);\n const entries = await fs.readdir(targetDir);\n\n if (entries.length === 0) {\n return true;\n }\n\n const isCurrentFolder = targetDir === cwd;\n const response = await prompts({\n type: \"confirm\",\n name: \"proceed\",\n message: isCurrentFolder\n ? `Current folder '${projectName}' is not empty. Continue anyway?`\n : `Target folder '${projectName}' already exists and is not empty. Continue anyway?`,\n initial: false,\n });\n\n return response.proceed === true;\n}\n\nexport async function init() {\n const cwd = process.cwd();\n const isExistingProject = await fs.pathExists(path.join(cwd, \"package.json\"));\n const existingZuroConfig = await readZuroConfig(cwd);\n\n if (isExistingProject && !existingZuroConfig) {\n showNonZuroProjectMessage();\n return;\n }\n\n let targetDir = cwd;\n let pm = \"npm\";\n let srcDir = \"src\";\n let projectName = path.basename(cwd);\n\n if (isExistingProject) {\n console.log(chalk.blue(\"ℹ Existing project detected.\"));\n\n projectName = path.basename(cwd);\n\n if (await fs.pathExists(path.join(cwd, \"pnpm-lock.yaml\"))) {\n pm = \"pnpm\";\n } else if (await fs.pathExists(path.join(cwd, \"bun.lockb\"))) {\n pm = \"bun\";\n } else if (await fs.pathExists(path.join(cwd, \"yarn.lock\"))) {\n pm = \"yarn\";\n }\n\n const response = await prompts({\n type: \"text\",\n name: \"srcDir\",\n message: \"Where is your source code located?\",\n initial: \"src\",\n });\n\n srcDir = response.srcDir || \"src\";\n } else {\n console.log(chalk.dim(` Tip: Leave blank to use current folder (${path.basename(cwd)})\\n`));\n\n const response = await prompts([\n {\n type: \"text\",\n name: \"path\",\n message: \"Project name (blank for current folder)\",\n initial: \"\",\n },\n {\n type: \"select\",\n name: \"pm\",\n message: \"Package Manager?\",\n choices: [\n { title: \"npm\", value: \"npm\" },\n { title: \"pnpm\", value: \"pnpm\" },\n { title: \"bun\", value: \"bun\" },\n ],\n initial: 0,\n },\n ]);\n\n if (response.pm === undefined) {\n console.log(chalk.red(\"Operation cancelled.\"));\n return;\n }\n\n pm = response.pm;\n srcDir = \"src\";\n\n if (!response.path || response.path.trim() === \"\") {\n projectName = path.basename(cwd);\n targetDir = cwd;\n console.log(chalk.blue(`ℹ Using current folder: ${projectName}`));\n } else {\n projectName = response.path.trim();\n targetDir = path.resolve(cwd, projectName);\n }\n\n const isSafeTarget = await ensureSafeTargetDirectory(targetDir, cwd, projectName);\n if (!isSafeTarget) {\n console.log(chalk.red(\"Operation cancelled.\"));\n return;\n }\n }\n\n const existingConfig = targetDir === cwd ? existingZuroConfig : await readZuroConfig(targetDir);\n\n const zuroConfig: ZuroConfig = {\n name: projectName,\n pm,\n srcDir: srcDir || existingConfig?.srcDir || \"src\",\n };\n\n const spinner = ora(\"Connecting to Zuro Registry...\").start();\n let currentStep = \"package manager preflight\";\n\n try {\n spinner.text = `Checking ${pm} availability...`;\n await ensurePackageManagerAvailable(pm);\n\n currentStep = \"registry fetch\";\n spinner.text = \"Connecting to Zuro Registry...\";\n const registryContext = await fetchRegistry();\n\n const coreModule = registryContext.manifest.modules.core;\n\n if (!coreModule) {\n spinner.fail(\"Core module not found in registry.\");\n return;\n }\n\n currentStep = \"project initialization\";\n spinner.text = \"Initializing project...\";\n\n const hasPackageJson = await fs.pathExists(path.join(targetDir, \"package.json\"));\n if (!hasPackageJson) {\n await initPackageJson(targetDir, true, projectName, srcDir);\n }\n\n currentStep = \"dependency installation\";\n spinner.text = `Installing dependencies using ${pm}...`;\n\n let runtimeDeps: string[] = [];\n let devDeps: string[] = [];\n\n if (isExistingProject) {\n const safeDeps = [\"zod\", \"dotenv\"];\n const coreDeps = coreModule.dependencies || [];\n runtimeDeps = coreDeps.filter((dependency) => safeDeps.includes(dependency));\n devDeps = coreModule.devDependencies || [];\n } else {\n runtimeDeps = coreModule.dependencies || [];\n devDeps = coreModule.devDependencies || [];\n }\n\n await installDependencies(pm, runtimeDeps, targetDir);\n await installDependencies(pm, devDeps, targetDir, { dev: true });\n\n currentStep = \"module file generation\";\n spinner.text = \"Fetching core module files...\";\n\n for (const file of coreModule.files) {\n const { relativeTargetPath, targetPath } = resolveSafeTargetPath(targetDir, srcDir, file);\n const fileName = path.basename(targetPath);\n\n if (isExistingProject) {\n if (fileName === \"app.ts\" || fileName === \"server.ts\") {\n continue;\n }\n\n const relativeParts = relativeTargetPath.split(path.sep);\n const isSafe = fileName === \"env.ts\" || relativeParts.includes(\"lib\");\n if (!isSafe) {\n continue;\n }\n }\n\n const content = await fetchFile(file.path, {\n baseUrl: registryContext.fileBaseUrl,\n expectedSha256: file.sha256,\n expectedSize: file.size,\n });\n\n await fs.ensureDir(path.dirname(targetPath));\n await fs.writeFile(targetPath, content);\n }\n\n currentStep = \"environment file setup\";\n await createInitialEnv(targetDir);\n\n currentStep = \"config write\";\n await writeZuroConfig(targetDir, zuroConfig);\n\n spinner.succeed(chalk.green(\"Project initialized successfully!\"));\n\n console.log(`\\n${chalk.bold(\"Next steps:\")}`);\n if (targetDir !== cwd) {\n console.log(chalk.cyan(` cd ${projectName}`));\n }\n console.log(chalk.cyan(` ${pm} run dev`));\n console.log(`\\n${chalk.dim(\"Add modules: zuro-cli add database, zuro-cli add auth\")}`);\n } catch (error) {\n spinner.fail(chalk.red(`Failed during ${currentStep}.`));\n const errorMessage = error instanceof Error ? error.message : String(error);\n console.error(chalk.red(errorMessage));\n console.log(`\\n${chalk.bold(\"Retry:\")}`);\n if (targetDir !== cwd) {\n console.log(chalk.cyan(` cd ${projectName}`));\n }\n console.log(chalk.cyan(\" npx zuro-cli init\"));\n }\n}\n","import { createHash } from \"node:crypto\";\n\nconst DEFAULT_REGISTRY_BASE_URL = \"https://registry.devbybriyan.com\";\nconst DEFAULT_REGISTRY_ENTRY_URL = `${DEFAULT_REGISTRY_BASE_URL}/channels/stable.json`;\nconst REGISTRY_ENV_VAR = \"ZURO_REGISTRY_URL\";\nconst REQUEST_TIMEOUT_MS = 8000;\nconst MAX_RETRIES = 2;\n\nexport interface RegistryFile {\n path: string;\n target: string;\n type: string;\n sha256?: string;\n size?: number;\n}\n\nexport interface RegistryModule {\n type: string;\n files: RegistryFile[];\n moduleDependencies?: string[];\n dependencies?: string[];\n devDependencies?: string[];\n}\n\nexport interface RegistryManifest {\n schemaVersion?: number;\n status?: string;\n templateVersion?: string;\n generatedAt?: string;\n modules: Record<string, RegistryModule>;\n}\n\ninterface RegistryChannelPointer {\n schemaVersion?: number;\n channel?: string;\n templateVersion?: string;\n generatedAt?: string;\n indexPath?: string;\n indexUrl?: string;\n}\n\nexport interface RegistryContext {\n manifest: RegistryManifest;\n manifestUrl: string;\n fileBaseUrl: string;\n}\n\ninterface FetchFileOptions {\n baseUrl: string;\n expectedSha256?: string;\n expectedSize?: number;\n}\n\nexport function getRegistryUrl() {\n return resolveRegistryEntryUrl();\n}\n\nfunction withTrailingSlash(url: string) {\n return url.endsWith(\"/\") ? url : `${url}/`;\n}\n\nfunction resolveRegistryEntryUrl() {\n const override = process.env[REGISTRY_ENV_VAR]?.trim();\n\n if (!override) {\n return DEFAULT_REGISTRY_ENTRY_URL;\n }\n\n let parsed: URL;\n\n try {\n parsed = new URL(override);\n } catch {\n throw new Error(\n `Invalid ${REGISTRY_ENV_VAR} value '${override}'. Expected a valid http(s) URL.`\n );\n }\n\n if (parsed.pathname.endsWith(\".json\")) {\n return parsed.toString();\n }\n\n return new URL(\"channels/stable.json\", withTrailingSlash(parsed.toString())).toString();\n}\n\nfunction isRegistryManifest(data: unknown): data is RegistryManifest {\n if (!data || typeof data !== \"object\") {\n return false;\n }\n\n const candidate = data as Partial<RegistryManifest>;\n return !!candidate.modules && typeof candidate.modules === \"object\";\n}\n\nfunction isChannelPointer(data: unknown): data is RegistryChannelPointer {\n if (!data || typeof data !== \"object\") {\n return false;\n }\n\n const candidate = data as Partial<RegistryChannelPointer>;\n return typeof candidate.indexPath === \"string\" || typeof candidate.indexUrl === \"string\";\n}\n\nfunction delay(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nasync function fetchWithRetry(url: string): Promise<Response> {\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);\n\n try {\n const response = await fetch(url, {\n headers: { Accept: \"application/json, text/plain, */*\" },\n signal: controller.signal,\n });\n\n if (response.ok) {\n return response;\n }\n\n const shouldRetry = response.status >= 500 && attempt < MAX_RETRIES;\n if (shouldRetry) {\n await delay(250 * (attempt + 1));\n continue;\n }\n\n throw new Error(`Request failed (${response.status} ${response.statusText}) for ${url}`);\n } catch (error) {\n lastError = error;\n\n if (attempt === MAX_RETRIES) {\n break;\n }\n\n await delay(250 * (attempt + 1));\n } finally {\n clearTimeout(timeout);\n }\n }\n\n if (lastError instanceof Error) {\n throw lastError;\n }\n\n throw new Error(`Failed to fetch ${url}`);\n}\n\nasync function fetchJson<T>(url: string): Promise<{ data: T; resolvedUrl: string }> {\n const response = await fetchWithRetry(url);\n const data = (await response.json()) as T;\n\n return {\n data,\n resolvedUrl: response.url || url,\n };\n}\n\nfunction resolveManifestUrl(pointer: RegistryChannelPointer, pointerUrl: string): string {\n const explicit = pointer.indexUrl || pointer.indexPath;\n\n if (!explicit) {\n throw new Error(\"Registry channel pointer is missing indexUrl/indexPath\");\n }\n\n return new URL(explicit, pointerUrl).toString();\n}\n\nexport async function fetchRegistry(): Promise<RegistryContext> {\n const registryEntryUrl = resolveRegistryEntryUrl();\n let entry: { data: unknown; resolvedUrl: string };\n\n try {\n entry = await fetchJson<unknown>(registryEntryUrl);\n } catch (error) {\n throw new Error(\n `Unable to fetch registry from ${registryEntryUrl}. For local testing set ${REGISTRY_ENV_VAR}=http://127.0.0.1:8787.`,\n { cause: error as Error }\n );\n }\n\n if (isRegistryManifest(entry.data)) {\n return {\n manifest: entry.data,\n manifestUrl: entry.resolvedUrl,\n fileBaseUrl: withTrailingSlash(new URL(\".\", entry.resolvedUrl).toString()),\n };\n }\n\n if (!isChannelPointer(entry.data)) {\n throw new Error(\n `Invalid registry payload at ${registryEntryUrl}. Expected manifest or channel pointer.`\n );\n }\n\n const manifestUrl = resolveManifestUrl(entry.data, entry.resolvedUrl);\n const manifestResult = await fetchJson<unknown>(manifestUrl);\n\n if (!isRegistryManifest(manifestResult.data)) {\n throw new Error(`Invalid manifest payload at ${manifestUrl}.`);\n }\n\n return {\n manifest: manifestResult.data,\n manifestUrl: manifestResult.resolvedUrl,\n fileBaseUrl: withTrailingSlash(new URL(\".\", manifestResult.resolvedUrl).toString()),\n };\n}\n\nexport async function fetchFile(filePath: string, options: FetchFileOptions) {\n const normalizedPath = filePath.replace(/^\\//, \"\");\n const fileUrl = new URL(normalizedPath, withTrailingSlash(options.baseUrl)).toString();\n const response = await fetchWithRetry(fileUrl);\n const content = await response.text();\n\n if (typeof options.expectedSize === \"number\") {\n const actualSize = Buffer.byteLength(content, \"utf8\");\n if (actualSize !== options.expectedSize) {\n throw new Error(\n `Size mismatch for ${filePath}. Expected ${options.expectedSize}, got ${actualSize}.`\n );\n }\n }\n\n if (options.expectedSha256) {\n const actualSha256 = createHash(\"sha256\").update(content, \"utf8\").digest(\"hex\");\n if (actualSha256 !== options.expectedSha256) {\n throw new Error(\n `Checksum mismatch for ${filePath}. Expected ${options.expectedSha256}, got ${actualSha256}.`\n );\n }\n }\n\n return content;\n}\n","import fs from \"fs-extra\";\nimport path from \"path\";\nimport { execa } from \"execa\";\n\nfunction normalizePackageName(name: string) {\n const normalized = name\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9._-]/g, \"-\")\n .replace(/-+/g, \"-\")\n .replace(/^[._-]+|[._-]+$/g, \"\");\n\n return normalized || \"zuro-app\";\n}\n\nexport async function ensurePackageManagerAvailable(pm: string) {\n try {\n await execa(pm, [\"--version\"], { stdio: \"ignore\" });\n } catch {\n throw new Error(\n `Package manager '${pm}' is not installed or not available in PATH. Install it or choose npm.`\n );\n }\n}\n\nexport async function initPackageJson(\n cwd: string,\n force: boolean = false,\n packageName = \"zuro-app\",\n srcDir = \"src\"\n) {\n const pkgPath = path.join(cwd, \"package.json\");\n if (force || !await fs.pathExists(pkgPath)) {\n await fs.writeJson(pkgPath, {\n name: normalizePackageName(packageName),\n version: \"0.0.1\",\n private: true,\n scripts: {\n \"dev\": `tsx watch ${srcDir}/server.ts`,\n \"build\": \"tsc\",\n \"start\": \"node dist/server.js\"\n }\n }, { spaces: 2 });\n }\n}\n\ninterface InstallOptions {\n dev?: boolean;\n}\n\nexport async function installDependencies(\n pm: string,\n deps: string[],\n cwd: string,\n options: InstallOptions = {}\n) {\n const uniqueDeps = [...new Set(deps)].filter(Boolean);\n\n if (uniqueDeps.length === 0) {\n return;\n }\n\n const isDev = options.dev ?? false;\n\n if (pm === \"npm\") {\n const args = [\"install\", ...(isDev ? [\"--save-dev\"] : []), ...uniqueDeps];\n await execa(\"npm\", args, { cwd });\n return;\n }\n\n if (pm === \"pnpm\") {\n const args = [\"add\", ...(isDev ? [\"-D\"] : []), ...uniqueDeps];\n await execa(\"pnpm\", args, { cwd });\n return;\n }\n\n if (pm === \"yarn\") {\n const args = [\"add\", ...(isDev ? [\"-D\"] : []), ...uniqueDeps];\n await execa(\"yarn\", args, { cwd });\n return;\n }\n\n if (pm === \"bun\") {\n const args = [\"add\", ...(isDev ? [\"-d\"] : []), ...uniqueDeps];\n await execa(\"bun\", args, { cwd });\n return;\n }\n\n throw new Error(`Unsupported package manager: ${pm}`);\n}\n","import fs from \"fs-extra\";\r\nimport path from \"path\";\r\nimport os from \"os\";\r\n\r\n/**\r\n * Creates or updates .env file with new variables\r\n */\r\nexport const updateEnvFile = async (\r\n cwd: string,\r\n variables: Record<string, string>,\r\n createIfMissing = true\r\n) => {\r\n const envPath = path.join(cwd, \".env\");\r\n\r\n let content = \"\";\r\n if (fs.existsSync(envPath)) {\r\n content = await fs.readFile(envPath, \"utf-8\");\r\n } else if (!createIfMissing) {\r\n return;\r\n }\r\n\r\n let modified = false;\r\n\r\n for (const [key, value] of Object.entries(variables)) {\r\n // Check if key already exists\r\n const regex = new RegExp(`^${key}=`, \"m\");\r\n if (!regex.test(content)) {\r\n // Add newline if content doesn't end with one\r\n if (content && !content.endsWith(\"\\n\")) {\r\n content += os.EOL;\r\n }\r\n content += `${key}=${value}${os.EOL}`;\r\n modified = true;\r\n }\r\n }\r\n\r\n if (modified || !fs.existsSync(envPath)) {\r\n await fs.writeFile(envPath, content);\r\n }\r\n};\r\n\r\n/**\r\n * Updates env.ts to add new schema fields\r\n */\r\nexport const updateEnvSchema = async (\r\n cwd: string,\r\n srcDir: string,\r\n fields: Array<{ name: string; schema: string }>\r\n) => {\r\n const envPath = path.join(cwd, srcDir, \"env.ts\");\r\n\r\n if (!fs.existsSync(envPath)) {\r\n return false;\r\n }\r\n\r\n let content = await fs.readFile(envPath, \"utf-8\");\r\n let modified = false;\r\n\r\n for (const field of fields) {\r\n // Check if field already exists in schema\r\n if (content.includes(`${field.name}:`)) {\r\n continue;\r\n }\r\n\r\n // Find the closing of envSchema z.object({ ... })\r\n // Insert before the closing });\r\n const schemaEndRegex = /(\\n\\s*)(}\\);?\\s*\\n\\s*export const env)/;\r\n const match = content.match(schemaEndRegex);\r\n\r\n if (match) {\r\n const indent = \" \"; // 4 spaces\r\n const newField = `${indent}${field.name}: ${field.schema},\\n`;\r\n content = content.replace(\r\n schemaEndRegex,\r\n `\\n${newField}$1$2`\r\n );\r\n modified = true;\r\n }\r\n }\r\n\r\n if (modified) {\r\n await fs.writeFile(envPath, content);\r\n }\r\n\r\n return modified;\r\n};\r\n\r\n/**\r\n * Creates initial .env file for new projects\r\n */\r\nexport const createInitialEnv = async (cwd: string) => {\r\n const envPath = path.join(cwd, \".env\");\r\n\r\n if (fs.existsSync(envPath)) {\r\n return; // Don't overwrite existing\r\n }\r\n\r\n const content = `# Environment Variables\r\nPORT=3000\r\nNODE_ENV=development\r\n`;\r\n\r\n await fs.writeFile(envPath, content);\r\n};\r\n\r\n/**\r\n * Module-specific env configurations\r\n */\r\nexport const ENV_CONFIGS = {\r\n \"database-pg\": {\r\n envVars: {\r\n DATABASE_URL: \"postgresql://postgres@localhost:5432/mydb\",\r\n },\r\n schemaFields: [\r\n { name: \"DATABASE_URL\", schema: \"z.string().url()\" },\r\n ],\r\n },\r\n \"database-mysql\": {\r\n envVars: {\r\n DATABASE_URL: \"mysql://root@localhost:3306/mydb\",\r\n },\r\n schemaFields: [\r\n { name: \"DATABASE_URL\", schema: \"z.string().url()\" },\r\n ],\r\n },\r\n auth: {\r\n envVars: {\r\n BETTER_AUTH_SECRET: \"your-secret-key-at-least-32-characters-long\",\r\n BETTER_AUTH_URL: \"http://localhost:3000\",\r\n },\r\n schemaFields: [\r\n { name: \"BETTER_AUTH_SECRET\", schema: \"z.string().min(32)\" },\r\n { name: \"BETTER_AUTH_URL\", schema: \"z.string().url()\" },\r\n ],\r\n },\r\n};\r\n","import fs from \"fs-extra\";\nimport path from \"path\";\n\nexport interface ZuroConfig {\n name?: string;\n pm?: string;\n srcDir?: string;\n}\n\nfunction sanitizeConfig(input: unknown): ZuroConfig {\n if (!input || typeof input !== \"object\") {\n return {};\n }\n\n const raw = input as Record<string, unknown>;\n const config: ZuroConfig = {};\n\n if (typeof raw.name === \"string\") {\n config.name = raw.name;\n }\n\n if (typeof raw.pm === \"string\") {\n config.pm = raw.pm;\n }\n\n if (typeof raw.srcDir === \"string\") {\n config.srcDir = raw.srcDir;\n }\n\n return config;\n}\n\nexport function getConfigPath(cwd: string) {\n return path.join(cwd, \"zuro.json\");\n}\n\nexport async function readZuroConfig(cwd: string): Promise<ZuroConfig | null> {\n const configPath = getConfigPath(cwd);\n\n if (!(await fs.pathExists(configPath))) {\n return null;\n }\n\n const raw = await fs.readJson(configPath);\n return sanitizeConfig(raw);\n}\n\nexport async function writeZuroConfig(cwd: string, config: ZuroConfig) {\n const configPath = getConfigPath(cwd);\n await fs.writeJson(configPath, sanitizeConfig(config), { spaces: 2 });\n}\n","import chalk from \"chalk\";\n\nexport function showNonZuroProjectMessage() {\n console.log(chalk.yellow(\"This directory looks like an existing project that wasn't created with Zuro CLI.\"));\n console.log(\"\");\n console.log(chalk.yellow(\"We stopped here because we don't want to make unnecessary changes to your project.\"));\n console.log(\"\");\n console.log(\"Zuro CLI works in:\");\n console.log(\"- a fresh/empty directory, or\");\n console.log(\"- an existing project already managed by Zuro CLI.\");\n}\n","import prompts from \"prompts\";\nimport ora from \"ora\";\nimport path from \"path\";\nimport fs from \"fs-extra\";\nimport { fetchRegistry, fetchFile, RegistryFile } from \"../utils/registry\";\nimport { installDependencies } from \"../utils/pm\";\nimport { resolveDependencies } from \"../utils/dependency\";\nimport { updateEnvFile, updateEnvSchema, ENV_CONFIGS } from \"../utils/env-manager\";\nimport chalk from \"chalk\";\nimport { readZuroConfig } from \"../utils/config\";\nimport { showNonZuroProjectMessage } from \"../utils/project-guard\";\n\nfunction resolveSafeTargetPath(projectRoot: string, srcDir: string, file: RegistryFile) {\n const targetPath = path.resolve(projectRoot, srcDir, file.target);\n const normalizedRoot = path.resolve(projectRoot);\n\n if (targetPath !== normalizedRoot && !targetPath.startsWith(`${normalizedRoot}${path.sep}`)) {\n throw new Error(`Refusing to write outside project directory: ${file.target}`);\n }\n\n return targetPath;\n}\n\n/**\n * Modifies app.ts to include error handler middleware\n */\nasync function injectErrorHandler(projectRoot: string, srcDir: string): Promise<boolean> {\n const appPath = path.join(projectRoot, srcDir, \"app.ts\");\n\n if (!fs.existsSync(appPath)) {\n return false;\n }\n\n let content = await fs.readFile(appPath, \"utf-8\");\n\n if (content.includes(\"errorHandler\")) {\n return true;\n }\n\n const errorImport = `import { errorHandler, notFoundHandler } from \"./middleware/error-handler\";`;\n\n const importRegex = /^import .+ from .+;?\\s*$/gm;\n let lastImportIndex = 0;\n let match;\n\n while ((match = importRegex.exec(content)) !== null) {\n lastImportIndex = match.index + match[0].length;\n }\n\n if (lastImportIndex > 0) {\n content = content.slice(0, lastImportIndex) + `\\n${errorImport}` + content.slice(lastImportIndex);\n }\n\n const errorSetup = `\\n// Error handling (must be last)\\napp.use(notFoundHandler);\\napp.use(errorHandler);\\n`;\n const exportMatch = content.match(/export default app;?\\s*$/m);\n if (exportMatch && exportMatch.index !== undefined) {\n content = content.slice(0, exportMatch.index) + errorSetup + \"\\n\" + content.slice(exportMatch.index);\n }\n\n await fs.writeFile(appPath, content);\n return true;\n}\n\n/**\n * Modifies app.ts to include auth routes\n */\nasync function injectAuthRoutes(projectRoot: string, srcDir: string): Promise<boolean> {\n const appPath = path.join(projectRoot, srcDir, \"app.ts\");\n\n if (!fs.existsSync(appPath)) {\n return false;\n }\n\n let content = await fs.readFile(appPath, \"utf-8\");\n\n if (content.includes(\"routes/auth.routes\")) {\n return true;\n }\n\n const authImport = `import authRoutes from \"./routes/auth.routes\";`;\n const userImport = `import userRoutes from \"./routes/user.routes\";`;\n const routeSetup = `\\n// Auth routes\\napp.use(authRoutes);\\napp.use(\"/api/users\", userRoutes);\\n`;\n\n const importRegex = /^import .+ from .+;?\\s*$/gm;\n let lastImportIndex = 0;\n let match;\n\n while ((match = importRegex.exec(content)) !== null) {\n lastImportIndex = match.index + match[0].length;\n }\n\n if (lastImportIndex > 0) {\n content = content.slice(0, lastImportIndex) + `\\n${authImport}\\n${userImport}` + content.slice(lastImportIndex);\n }\n\n const exportMatch = content.match(/export default app;?\\s*$/m);\n if (exportMatch && exportMatch.index !== undefined) {\n content = content.slice(0, exportMatch.index) + routeSetup + \"\\n\" + content.slice(exportMatch.index);\n }\n\n await fs.writeFile(appPath, content);\n return true;\n}\n\nexport const add = async (moduleName: string) => {\n const projectRoot = process.cwd();\n const projectConfig = await readZuroConfig(projectRoot);\n if (!projectConfig) {\n showNonZuroProjectMessage();\n return;\n }\n let srcDir = projectConfig.srcDir || \"src\";\n\n let customDbUrl: string | undefined;\n\n const DEFAULT_URLS = {\n \"database-pg\": \"postgresql://root@localhost:5432/mydb\",\n \"database-mysql\": \"mysql://root@localhost:3306/mydb\",\n };\n\n if (moduleName === \"database\") {\n const variantResponse = await prompts({\n type: \"select\",\n name: \"variant\",\n message: \"Which database dialect?\",\n choices: [\n { title: \"PostgreSQL\", value: \"database-pg\" },\n { title: \"MySQL\", value: \"database-mysql\" },\n ],\n });\n\n if (!variantResponse.variant) {\n process.exit(0);\n }\n\n moduleName = variantResponse.variant;\n\n const defaultUrl = DEFAULT_URLS[moduleName as keyof typeof DEFAULT_URLS];\n console.log(chalk.dim(` Tip: Leave blank to use ${defaultUrl}\\n`));\n\n const urlResponse = await prompts({\n type: \"text\",\n name: \"dbUrl\",\n message: \"Database URL\",\n initial: \"\",\n });\n customDbUrl = urlResponse.dbUrl?.trim() || defaultUrl;\n }\n\n if ((moduleName === \"database-pg\" || moduleName === \"database-mysql\") && customDbUrl === undefined) {\n const defaultUrl = DEFAULT_URLS[moduleName as keyof typeof DEFAULT_URLS];\n console.log(chalk.dim(` Tip: Leave blank to use ${defaultUrl}\\n`));\n\n const response = await prompts({\n type: \"text\",\n name: \"dbUrl\",\n message: \"Database URL\",\n initial: \"\",\n });\n customDbUrl = response.dbUrl?.trim() || defaultUrl;\n }\n\n const spinner = ora(`Checking registry for ${moduleName}...`).start();\n\n try {\n const registryContext = await fetchRegistry();\n const module = registryContext.manifest.modules[moduleName];\n\n if (!module) {\n spinner.fail(`Module '${moduleName}' not found.`);\n return;\n }\n\n spinner.succeed(`Found module: ${chalk.cyan(moduleName)}`);\n\n const moduleDeps = module.moduleDependencies || [];\n await resolveDependencies(moduleDeps, projectRoot);\n\n spinner.start(\"Installing dependencies...\");\n\n let pm = \"npm\";\n if (fs.existsSync(path.join(projectRoot, \"pnpm-lock.yaml\"))) {\n pm = \"pnpm\";\n } else if (fs.existsSync(path.join(projectRoot, \"bun.lockb\"))) {\n pm = \"bun\";\n } else if (fs.existsSync(path.join(projectRoot, \"yarn.lock\"))) {\n pm = \"yarn\";\n }\n\n await installDependencies(pm, module.dependencies || [], projectRoot);\n await installDependencies(pm, module.devDependencies || [], projectRoot, { dev: true });\n\n spinner.succeed(\"Dependencies installed\");\n\n spinner.start(\"Scaffolding files...\");\n\n for (const file of module.files) {\n const content = await fetchFile(file.path, {\n baseUrl: registryContext.fileBaseUrl,\n expectedSha256: file.sha256,\n expectedSize: file.size,\n });\n\n const targetPath = resolveSafeTargetPath(projectRoot, srcDir, file);\n\n await fs.ensureDir(path.dirname(targetPath));\n await fs.writeFile(targetPath, content);\n }\n\n spinner.succeed(\"Files generated\");\n\n if (moduleName === \"auth\") {\n spinner.start(\"Configuring routes in app.ts...\");\n const injected = await injectAuthRoutes(projectRoot, srcDir);\n if (injected) {\n spinner.succeed(\"Routes configured in app.ts\");\n } else {\n spinner.warn(\"Could not find app.ts - routes need manual setup\");\n }\n }\n\n if (moduleName === \"error-handler\") {\n spinner.start(\"Configuring error handler in app.ts...\");\n const injected = await injectErrorHandler(projectRoot, srcDir);\n if (injected) {\n spinner.succeed(\"Error handler configured in app.ts\");\n } else {\n spinner.warn(\"Could not find app.ts - error handler needs manual setup\");\n }\n }\n\n const envConfig = ENV_CONFIGS[moduleName as keyof typeof ENV_CONFIGS];\n if (envConfig) {\n spinner.start(\"Updating environment configuration...\");\n\n const envVars: Record<string, string> = { ...envConfig.envVars };\n if (customDbUrl && (moduleName === \"database-pg\" || moduleName === \"database-mysql\")) {\n envVars.DATABASE_URL = customDbUrl;\n }\n\n await updateEnvFile(projectRoot, envVars);\n await updateEnvSchema(projectRoot, srcDir, envConfig.schemaFields);\n\n spinner.succeed(\"Environment configured\");\n }\n\n console.log(chalk.green(`\\n✔ ${moduleName} added successfully!\\n`));\n\n if (moduleName === \"auth\") {\n console.log(chalk.bold(\"📋 Next Steps:\\n\"));\n console.log(chalk.yellow(\"1. Update your .env file:\"));\n console.log(\n chalk.dim(\" We added placeholder values. Update BETTER_AUTH_SECRET with a secure key.\\n\")\n );\n console.log(chalk.yellow(\"2. Run database migrations:\"));\n console.log(chalk.cyan(\" npx drizzle-kit generate\"));\n console.log(chalk.cyan(\" npx drizzle-kit migrate\\n\"));\n console.log(chalk.yellow(\"3. Available endpoints:\"));\n console.log(chalk.dim(\" POST /auth/sign-up/email - Register\"));\n console.log(chalk.dim(\" POST /auth/sign-in/email - Login\"));\n console.log(chalk.dim(\" POST /auth/sign-out - Logout\"));\n console.log(chalk.dim(\" GET /api/users/me - Current user\\n\"));\n } else if (moduleName === \"error-handler\") {\n console.log(chalk.bold(\"📋 Usage:\\n\"));\n console.log(chalk.yellow(\"Throw errors in your controllers:\"));\n console.log(chalk.dim(\" ─────────────────────────────────────\"));\n console.log(chalk.white(` import { UnauthorizedError, NotFoundError } from \"./lib/errors\";`));\n console.log(\"\");\n console.log(chalk.white(` throw new UnauthorizedError(\"Invalid credentials\");`));\n console.log(chalk.white(` throw new NotFoundError(\"User not found\");`));\n console.log(chalk.dim(\" ─────────────────────────────────────\\n\"));\n console.log(chalk.yellow(\"Available error classes:\"));\n console.log(chalk.dim(\" BadRequestError (400)\"));\n console.log(chalk.dim(\" UnauthorizedError (401)\"));\n console.log(chalk.dim(\" ForbiddenError (403)\"));\n console.log(chalk.dim(\" NotFoundError (404)\"));\n console.log(chalk.dim(\" ConflictError (409)\"));\n console.log(chalk.dim(\" ValidationError (422)\"));\n console.log(chalk.dim(\" InternalServerError (500)\\n\"));\n console.log(chalk.yellow(\"Wrap async handlers:\"));\n console.log(chalk.dim(\" ─────────────────────────────────────\"));\n console.log(chalk.white(` import { asyncHandler } from \"./middleware/error-handler\";`));\n console.log(\"\");\n console.log(chalk.white(` router.get(\"/users\", asyncHandler(async (req, res) => {`));\n console.log(chalk.white(\" // errors auto-caught\"));\n console.log(chalk.white(\" }));\"));\n console.log(chalk.dim(\" ─────────────────────────────────────\\n\"));\n } else if (moduleName.includes(\"database\")) {\n console.log(chalk.bold(\"📋 Next Steps:\\n\"));\n let stepNum = 1;\n\n if (!customDbUrl) {\n console.log(chalk.yellow(`${stepNum}. Update DATABASE_URL in .env:`));\n console.log(\n chalk.dim(\" We added a placeholder. Update with your actual database credentials.\\n\")\n );\n stepNum++;\n }\n\n console.log(chalk.yellow(`${stepNum}. Create schemas in src/db/schema/:`));\n console.log(chalk.dim(\" Add table files and export from index.ts\\n\"));\n stepNum++;\n\n console.log(chalk.yellow(`${stepNum}. Run migrations:`));\n console.log(chalk.cyan(\" npx drizzle-kit generate\"));\n console.log(chalk.cyan(\" npx drizzle-kit migrate\\n\"));\n }\n } catch (error) {\n spinner.fail(`Failed to add module: ${(error as Error).message}`);\n }\n};\n","import { add } from \"../commands/add\";\nimport { readZuroConfig } from \"./config\";\nimport fs from \"fs-extra\";\nimport path from \"path\";\nimport chalk from \"chalk\";\n\n// Signature files to check if a Zuro module is installed\nconst BLOCK_SIGNATURES: Record<string, string> = {\n core: \"env.ts\",\n \"database-pg\": \"db/index.ts\",\n \"database-mysql\": \"db/index.ts\",\n validator: \"middleware/validate.ts\",\n \"error-handler\": \"lib/errors.ts\",\n logger: \"lib/logger.ts\",\n auth: \"lib/auth.ts\",\n};\n\n/**\n * Resolves Zuro module dependencies (NOT npm packages).\n * Only handles module dependencies like \"core\", \"database\", \"validator\", \"auth\".\n */\nexport const resolveDependencies = async (\n moduleDependencies: string[] | undefined,\n cwd: string\n) => {\n if (!moduleDependencies || moduleDependencies.length === 0) {\n return;\n }\n\n const config = await readZuroConfig(cwd);\n const srcDir = config?.srcDir || \"src\";\n\n for (const dep of moduleDependencies) {\n if (dep === \"database\") {\n const pgExists = fs.existsSync(path.join(cwd, srcDir, BLOCK_SIGNATURES[\"database-pg\"]));\n const mysqlExists = fs.existsSync(path.join(cwd, srcDir, BLOCK_SIGNATURES[\"database-mysql\"]));\n\n if (pgExists || mysqlExists) {\n continue;\n }\n\n console.log(chalk.blue(`ℹ Dependency '${dep}' is missing. Triggering install...`));\n await add(\"database\");\n continue;\n }\n\n const signature = BLOCK_SIGNATURES[dep];\n if (!signature) {\n continue;\n }\n\n if (fs.existsSync(path.join(cwd, srcDir, signature))) {\n continue;\n }\n\n console.log(chalk.blue(`ℹ Installing missing dependency: ${dep}...`));\n await add(dep);\n }\n};\n"],"mappings":"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","names":["import_chalk","import_fs_extra","import_path","path","fs","import_fs_extra","import_path","path","fs","os","import_fs_extra","import_path","path","fs","chalk","path","fs","prompts","chalk","ora","import_prompts","import_ora","import_path","import_fs_extra","import_fs_extra","import_path","import_chalk","fs","path","chalk","import_chalk","resolveSafeTargetPath","path","fs","prompts","chalk","ora","module"]}
package/dist/index.mjs CHANGED
@@ -12,7 +12,7 @@ import prompts from "prompts";
12
12
 
13
13
  // src/utils/registry.ts
14
14
  import { createHash } from "crypto";
15
- var DEFAULT_REGISTRY_BASE_URL = "https://zuro-cli.devbybriyan.com/registry";
15
+ var DEFAULT_REGISTRY_BASE_URL = "https://registry.devbybriyan.com";
16
16
  var DEFAULT_REGISTRY_ENTRY_URL = `${DEFAULT_REGISTRY_BASE_URL}/channels/stable.json`;
17
17
  var REGISTRY_ENV_VAR = "ZURO_REGISTRY_URL";
18
18
  var REQUEST_TIMEOUT_MS = 8e3;
@@ -166,15 +166,28 @@ async function fetchFile(filePath, options) {
166
166
  import fs from "fs-extra";
167
167
  import path from "path";
168
168
  import { execa } from "execa";
169
- async function initPackageJson(cwd, force = false) {
169
+ function normalizePackageName(name) {
170
+ const normalized = name.trim().toLowerCase().replace(/[^a-z0-9._-]/g, "-").replace(/-+/g, "-").replace(/^[._-]+|[._-]+$/g, "");
171
+ return normalized || "zuro-app";
172
+ }
173
+ async function ensurePackageManagerAvailable(pm) {
174
+ try {
175
+ await execa(pm, ["--version"], { stdio: "ignore" });
176
+ } catch {
177
+ throw new Error(
178
+ `Package manager '${pm}' is not installed or not available in PATH. Install it or choose npm.`
179
+ );
180
+ }
181
+ }
182
+ async function initPackageJson(cwd, force = false, packageName = "zuro-app", srcDir = "src") {
170
183
  const pkgPath = path.join(cwd, "package.json");
171
184
  if (force || !await fs.pathExists(pkgPath)) {
172
185
  await fs.writeJson(pkgPath, {
173
- name: "zuro-app",
186
+ name: normalizePackageName(packageName),
174
187
  version: "0.0.1",
175
188
  private: true,
176
189
  scripts: {
177
- "dev": "tsx watch src/server.ts",
190
+ "dev": `tsx watch ${srcDir}/server.ts`,
178
191
  "build": "tsc",
179
192
  "start": "node dist/server.js"
180
193
  }
@@ -368,6 +381,21 @@ function resolveSafeTargetPath(projectRoot, srcDir, file) {
368
381
  targetPath
369
382
  };
370
383
  }
384
+ async function ensureSafeTargetDirectory(targetDir, cwd, projectName) {
385
+ await fs4.ensureDir(targetDir);
386
+ const entries = await fs4.readdir(targetDir);
387
+ if (entries.length === 0) {
388
+ return true;
389
+ }
390
+ const isCurrentFolder = targetDir === cwd;
391
+ const response = await prompts({
392
+ type: "confirm",
393
+ name: "proceed",
394
+ message: isCurrentFolder ? `Current folder '${projectName}' is not empty. Continue anyway?` : `Target folder '${projectName}' already exists and is not empty. Continue anyway?`,
395
+ initial: false
396
+ });
397
+ return response.proceed === true;
398
+ }
371
399
  async function init() {
372
400
  const cwd = process.cwd();
373
401
  const isExistingProject = await fs4.pathExists(path4.join(cwd, "package.json"));
@@ -432,7 +460,11 @@ async function init() {
432
460
  } else {
433
461
  projectName = response.path.trim();
434
462
  targetDir = path4.resolve(cwd, projectName);
435
- await fs4.ensureDir(targetDir);
463
+ }
464
+ const isSafeTarget = await ensureSafeTargetDirectory(targetDir, cwd, projectName);
465
+ if (!isSafeTarget) {
466
+ console.log(chalk2.red("Operation cancelled."));
467
+ return;
436
468
  }
437
469
  }
438
470
  const existingConfig = targetDir === cwd ? existingZuroConfig : await readZuroConfig(targetDir);
@@ -441,20 +473,26 @@ async function init() {
441
473
  pm,
442
474
  srcDir: srcDir || existingConfig?.srcDir || "src"
443
475
  };
444
- await writeZuroConfig(targetDir, zuroConfig);
445
476
  const spinner = ora("Connecting to Zuro Registry...").start();
477
+ let currentStep = "package manager preflight";
446
478
  try {
479
+ spinner.text = `Checking ${pm} availability...`;
480
+ await ensurePackageManagerAvailable(pm);
481
+ currentStep = "registry fetch";
482
+ spinner.text = "Connecting to Zuro Registry...";
447
483
  const registryContext = await fetchRegistry();
448
484
  const coreModule = registryContext.manifest.modules.core;
449
485
  if (!coreModule) {
450
486
  spinner.fail("Core module not found in registry.");
451
487
  return;
452
488
  }
489
+ currentStep = "project initialization";
453
490
  spinner.text = "Initializing project...";
454
491
  const hasPackageJson = await fs4.pathExists(path4.join(targetDir, "package.json"));
455
492
  if (!hasPackageJson) {
456
- await initPackageJson(targetDir, true);
493
+ await initPackageJson(targetDir, true, projectName, srcDir);
457
494
  }
495
+ currentStep = "dependency installation";
458
496
  spinner.text = `Installing dependencies using ${pm}...`;
459
497
  let runtimeDeps = [];
460
498
  let devDeps = [];
@@ -469,6 +507,7 @@ async function init() {
469
507
  }
470
508
  await installDependencies(pm, runtimeDeps, targetDir);
471
509
  await installDependencies(pm, devDeps, targetDir, { dev: true });
510
+ currentStep = "module file generation";
472
511
  spinner.text = "Fetching core module files...";
473
512
  for (const file of coreModule.files) {
474
513
  const { relativeTargetPath, targetPath } = resolveSafeTargetPath(targetDir, srcDir, file);
@@ -491,7 +530,10 @@ async function init() {
491
530
  await fs4.ensureDir(path4.dirname(targetPath));
492
531
  await fs4.writeFile(targetPath, content);
493
532
  }
533
+ currentStep = "environment file setup";
494
534
  await createInitialEnv(targetDir);
535
+ currentStep = "config write";
536
+ await writeZuroConfig(targetDir, zuroConfig);
495
537
  spinner.succeed(chalk2.green("Project initialized successfully!"));
496
538
  console.log(`
497
539
  ${chalk2.bold("Next steps:")}`);
@@ -502,8 +544,15 @@ ${chalk2.bold("Next steps:")}`);
502
544
  console.log(`
503
545
  ${chalk2.dim("Add modules: zuro-cli add database, zuro-cli add auth")}`);
504
546
  } catch (error) {
505
- spinner.fail(chalk2.red("Failed to initialize project."));
506
- console.error(error);
547
+ spinner.fail(chalk2.red(`Failed during ${currentStep}.`));
548
+ const errorMessage = error instanceof Error ? error.message : String(error);
549
+ console.error(chalk2.red(errorMessage));
550
+ console.log(`
551
+ ${chalk2.bold("Retry:")}`);
552
+ if (targetDir !== cwd) {
553
+ console.log(chalk2.cyan(` cd ${projectName}`));
554
+ }
555
+ console.log(chalk2.cyan(" npx zuro-cli init"));
507
556
  }
508
557
  }
509
558
 
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/commands/init.ts","../src/utils/registry.ts","../src/utils/pm.ts","../src/utils/env-manager.ts","../src/utils/config.ts","../src/utils/project-guard.ts","../src/commands/add.ts","../src/utils/dependency.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from \"commander\";\nimport { init } from \"./commands/init\";\nimport { add } from \"./commands/add\";\n\nconst program = new Command();\n\nprogram\n .name(\"zuro-cli\")\n .description(\"Zuro CLI tool\")\n .version(\"0.0.1\");\n\nprogram\n .command(\"init\")\n .description(\"Initialize a new Zuro project\")\n .action(init);\n\nprogram\n .command(\"add <module>\")\n .description(\"Add a module to your project\")\n .action(add);\n\nprogram.parse(process.argv);\n","import ora from \"ora\";\nimport chalk from \"chalk\";\nimport fs from \"fs-extra\";\nimport path from \"path\";\nimport prompts from \"prompts\";\nimport { fetchRegistry, fetchFile, RegistryFile } from \"../utils/registry\";\nimport { initPackageJson, installDependencies } from \"../utils/pm\";\nimport { createInitialEnv } from \"../utils/env-manager\";\nimport { readZuroConfig, writeZuroConfig } from \"../utils/config\";\nimport { showNonZuroProjectMessage } from \"../utils/project-guard\";\nimport type { ZuroConfig } from \"../utils/config\";\n\nfunction resolveSafeTargetPath(projectRoot: string, srcDir: string, file: RegistryFile) {\n const relativeTargetPath = path.join(srcDir, file.target);\n const targetPath = path.resolve(projectRoot, relativeTargetPath);\n const normalizedRoot = path.resolve(projectRoot);\n\n if (targetPath !== normalizedRoot && !targetPath.startsWith(`${normalizedRoot}${path.sep}`)) {\n throw new Error(`Refusing to write outside project directory: ${file.target}`);\n }\n\n return {\n relativeTargetPath,\n targetPath,\n };\n}\n\nexport async function init() {\n const cwd = process.cwd();\n const isExistingProject = await fs.pathExists(path.join(cwd, \"package.json\"));\n const existingZuroConfig = await readZuroConfig(cwd);\n\n if (isExistingProject && !existingZuroConfig) {\n showNonZuroProjectMessage();\n return;\n }\n\n let targetDir = cwd;\n let pm = \"npm\";\n let srcDir = \"src\";\n let projectName = path.basename(cwd);\n\n if (isExistingProject) {\n console.log(chalk.blue(\"ℹ Existing project detected.\"));\n\n projectName = path.basename(cwd);\n\n if (await fs.pathExists(path.join(cwd, \"pnpm-lock.yaml\"))) {\n pm = \"pnpm\";\n } else if (await fs.pathExists(path.join(cwd, \"bun.lockb\"))) {\n pm = \"bun\";\n } else if (await fs.pathExists(path.join(cwd, \"yarn.lock\"))) {\n pm = \"yarn\";\n }\n\n const response = await prompts({\n type: \"text\",\n name: \"srcDir\",\n message: \"Where is your source code located?\",\n initial: \"src\",\n });\n\n srcDir = response.srcDir || \"src\";\n } else {\n console.log(chalk.dim(` Tip: Leave blank to use current folder (${path.basename(cwd)})\\n`));\n\n const response = await prompts([\n {\n type: \"text\",\n name: \"path\",\n message: \"Project name (blank for current folder)\",\n initial: \"\",\n },\n {\n type: \"select\",\n name: \"pm\",\n message: \"Package Manager?\",\n choices: [\n { title: \"npm\", value: \"npm\" },\n { title: \"pnpm\", value: \"pnpm\" },\n { title: \"bun\", value: \"bun\" },\n ],\n initial: 0,\n },\n ]);\n\n if (response.pm === undefined) {\n console.log(chalk.red(\"Operation cancelled.\"));\n return;\n }\n\n pm = response.pm;\n srcDir = \"src\";\n\n if (!response.path || response.path.trim() === \"\") {\n projectName = path.basename(cwd);\n targetDir = cwd;\n console.log(chalk.blue(`ℹ Using current folder: ${projectName}`));\n } else {\n projectName = response.path.trim();\n targetDir = path.resolve(cwd, projectName);\n await fs.ensureDir(targetDir);\n }\n }\n\n const existingConfig = targetDir === cwd ? existingZuroConfig : await readZuroConfig(targetDir);\n\n const zuroConfig: ZuroConfig = {\n name: projectName,\n pm,\n srcDir: srcDir || existingConfig?.srcDir || \"src\",\n };\n\n await writeZuroConfig(targetDir, zuroConfig);\n\n const spinner = ora(\"Connecting to Zuro Registry...\").start();\n\n try {\n const registryContext = await fetchRegistry();\n\n const coreModule = registryContext.manifest.modules.core;\n\n if (!coreModule) {\n spinner.fail(\"Core module not found in registry.\");\n return;\n }\n\n spinner.text = \"Initializing project...\";\n\n const hasPackageJson = await fs.pathExists(path.join(targetDir, \"package.json\"));\n if (!hasPackageJson) {\n await initPackageJson(targetDir, true);\n }\n\n spinner.text = `Installing dependencies using ${pm}...`;\n\n let runtimeDeps: string[] = [];\n let devDeps: string[] = [];\n\n if (isExistingProject) {\n const safeDeps = [\"zod\", \"dotenv\"];\n const coreDeps = coreModule.dependencies || [];\n runtimeDeps = coreDeps.filter((dependency) => safeDeps.includes(dependency));\n devDeps = coreModule.devDependencies || [];\n } else {\n runtimeDeps = coreModule.dependencies || [];\n devDeps = coreModule.devDependencies || [];\n }\n\n await installDependencies(pm, runtimeDeps, targetDir);\n await installDependencies(pm, devDeps, targetDir, { dev: true });\n\n spinner.text = \"Fetching core module files...\";\n\n for (const file of coreModule.files) {\n const { relativeTargetPath, targetPath } = resolveSafeTargetPath(targetDir, srcDir, file);\n const fileName = path.basename(targetPath);\n\n if (isExistingProject) {\n if (fileName === \"app.ts\" || fileName === \"server.ts\") {\n continue;\n }\n\n const relativeParts = relativeTargetPath.split(path.sep);\n const isSafe = fileName === \"env.ts\" || relativeParts.includes(\"lib\");\n if (!isSafe) {\n continue;\n }\n }\n\n const content = await fetchFile(file.path, {\n baseUrl: registryContext.fileBaseUrl,\n expectedSha256: file.sha256,\n expectedSize: file.size,\n });\n\n await fs.ensureDir(path.dirname(targetPath));\n await fs.writeFile(targetPath, content);\n }\n\n await createInitialEnv(targetDir);\n\n spinner.succeed(chalk.green(\"Project initialized successfully!\"));\n\n console.log(`\\n${chalk.bold(\"Next steps:\")}`);\n if (targetDir !== cwd) {\n console.log(chalk.cyan(` cd ${projectName}`));\n }\n console.log(chalk.cyan(` ${pm} run dev`));\n console.log(`\\n${chalk.dim(\"Add modules: zuro-cli add database, zuro-cli add auth\")}`);\n } catch (error) {\n spinner.fail(chalk.red(\"Failed to initialize project.\"));\n console.error(error);\n }\n}\n","import { createHash } from \"node:crypto\";\n\nconst DEFAULT_REGISTRY_BASE_URL = \"https://zuro-cli.devbybriyan.com/registry\";\nconst DEFAULT_REGISTRY_ENTRY_URL = `${DEFAULT_REGISTRY_BASE_URL}/channels/stable.json`;\nconst REGISTRY_ENV_VAR = \"ZURO_REGISTRY_URL\";\nconst REQUEST_TIMEOUT_MS = 8000;\nconst MAX_RETRIES = 2;\n\nexport interface RegistryFile {\n path: string;\n target: string;\n type: string;\n sha256?: string;\n size?: number;\n}\n\nexport interface RegistryModule {\n type: string;\n files: RegistryFile[];\n moduleDependencies?: string[];\n dependencies?: string[];\n devDependencies?: string[];\n}\n\nexport interface RegistryManifest {\n schemaVersion?: number;\n status?: string;\n templateVersion?: string;\n generatedAt?: string;\n modules: Record<string, RegistryModule>;\n}\n\ninterface RegistryChannelPointer {\n schemaVersion?: number;\n channel?: string;\n templateVersion?: string;\n generatedAt?: string;\n indexPath?: string;\n indexUrl?: string;\n}\n\nexport interface RegistryContext {\n manifest: RegistryManifest;\n manifestUrl: string;\n fileBaseUrl: string;\n}\n\ninterface FetchFileOptions {\n baseUrl: string;\n expectedSha256?: string;\n expectedSize?: number;\n}\n\nexport function getRegistryUrl() {\n return resolveRegistryEntryUrl();\n}\n\nfunction withTrailingSlash(url: string) {\n return url.endsWith(\"/\") ? url : `${url}/`;\n}\n\nfunction resolveRegistryEntryUrl() {\n const override = process.env[REGISTRY_ENV_VAR]?.trim();\n\n if (!override) {\n return DEFAULT_REGISTRY_ENTRY_URL;\n }\n\n let parsed: URL;\n\n try {\n parsed = new URL(override);\n } catch {\n throw new Error(\n `Invalid ${REGISTRY_ENV_VAR} value '${override}'. Expected a valid http(s) URL.`\n );\n }\n\n if (parsed.pathname.endsWith(\".json\")) {\n return parsed.toString();\n }\n\n return new URL(\"channels/stable.json\", withTrailingSlash(parsed.toString())).toString();\n}\n\nfunction isRegistryManifest(data: unknown): data is RegistryManifest {\n if (!data || typeof data !== \"object\") {\n return false;\n }\n\n const candidate = data as Partial<RegistryManifest>;\n return !!candidate.modules && typeof candidate.modules === \"object\";\n}\n\nfunction isChannelPointer(data: unknown): data is RegistryChannelPointer {\n if (!data || typeof data !== \"object\") {\n return false;\n }\n\n const candidate = data as Partial<RegistryChannelPointer>;\n return typeof candidate.indexPath === \"string\" || typeof candidate.indexUrl === \"string\";\n}\n\nfunction delay(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nasync function fetchWithRetry(url: string): Promise<Response> {\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);\n\n try {\n const response = await fetch(url, {\n headers: { Accept: \"application/json, text/plain, */*\" },\n signal: controller.signal,\n });\n\n if (response.ok) {\n return response;\n }\n\n const shouldRetry = response.status >= 500 && attempt < MAX_RETRIES;\n if (shouldRetry) {\n await delay(250 * (attempt + 1));\n continue;\n }\n\n throw new Error(`Request failed (${response.status} ${response.statusText}) for ${url}`);\n } catch (error) {\n lastError = error;\n\n if (attempt === MAX_RETRIES) {\n break;\n }\n\n await delay(250 * (attempt + 1));\n } finally {\n clearTimeout(timeout);\n }\n }\n\n if (lastError instanceof Error) {\n throw lastError;\n }\n\n throw new Error(`Failed to fetch ${url}`);\n}\n\nasync function fetchJson<T>(url: string): Promise<{ data: T; resolvedUrl: string }> {\n const response = await fetchWithRetry(url);\n const data = (await response.json()) as T;\n\n return {\n data,\n resolvedUrl: response.url || url,\n };\n}\n\nfunction resolveManifestUrl(pointer: RegistryChannelPointer, pointerUrl: string): string {\n const explicit = pointer.indexUrl || pointer.indexPath;\n\n if (!explicit) {\n throw new Error(\"Registry channel pointer is missing indexUrl/indexPath\");\n }\n\n return new URL(explicit, pointerUrl).toString();\n}\n\nexport async function fetchRegistry(): Promise<RegistryContext> {\n const registryEntryUrl = resolveRegistryEntryUrl();\n let entry: { data: unknown; resolvedUrl: string };\n\n try {\n entry = await fetchJson<unknown>(registryEntryUrl);\n } catch (error) {\n throw new Error(\n `Unable to fetch registry from ${registryEntryUrl}. For local testing set ${REGISTRY_ENV_VAR}=http://127.0.0.1:8787.`,\n { cause: error as Error }\n );\n }\n\n if (isRegistryManifest(entry.data)) {\n return {\n manifest: entry.data,\n manifestUrl: entry.resolvedUrl,\n fileBaseUrl: withTrailingSlash(new URL(\".\", entry.resolvedUrl).toString()),\n };\n }\n\n if (!isChannelPointer(entry.data)) {\n throw new Error(\n `Invalid registry payload at ${registryEntryUrl}. Expected manifest or channel pointer.`\n );\n }\n\n const manifestUrl = resolveManifestUrl(entry.data, entry.resolvedUrl);\n const manifestResult = await fetchJson<unknown>(manifestUrl);\n\n if (!isRegistryManifest(manifestResult.data)) {\n throw new Error(`Invalid manifest payload at ${manifestUrl}.`);\n }\n\n return {\n manifest: manifestResult.data,\n manifestUrl: manifestResult.resolvedUrl,\n fileBaseUrl: withTrailingSlash(new URL(\".\", manifestResult.resolvedUrl).toString()),\n };\n}\n\nexport async function fetchFile(filePath: string, options: FetchFileOptions) {\n const normalizedPath = filePath.replace(/^\\//, \"\");\n const fileUrl = new URL(normalizedPath, withTrailingSlash(options.baseUrl)).toString();\n const response = await fetchWithRetry(fileUrl);\n const content = await response.text();\n\n if (typeof options.expectedSize === \"number\") {\n const actualSize = Buffer.byteLength(content, \"utf8\");\n if (actualSize !== options.expectedSize) {\n throw new Error(\n `Size mismatch for ${filePath}. Expected ${options.expectedSize}, got ${actualSize}.`\n );\n }\n }\n\n if (options.expectedSha256) {\n const actualSha256 = createHash(\"sha256\").update(content, \"utf8\").digest(\"hex\");\n if (actualSha256 !== options.expectedSha256) {\n throw new Error(\n `Checksum mismatch for ${filePath}. Expected ${options.expectedSha256}, got ${actualSha256}.`\n );\n }\n }\n\n return content;\n}\n","import fs from \"fs-extra\";\nimport path from \"path\";\nimport { execa } from \"execa\";\n\nexport async function initPackageJson(cwd: string, force: boolean = false) {\n const pkgPath = path.join(cwd, \"package.json\");\n if (force || !await fs.pathExists(pkgPath)) {\n await fs.writeJson(pkgPath, {\n name: \"zuro-app\",\n version: \"0.0.1\",\n private: true,\n scripts: {\n \"dev\": \"tsx watch src/server.ts\",\n \"build\": \"tsc\",\n \"start\": \"node dist/server.js\"\n }\n }, { spaces: 2 });\n }\n}\n\ninterface InstallOptions {\n dev?: boolean;\n}\n\nexport async function installDependencies(\n pm: string,\n deps: string[],\n cwd: string,\n options: InstallOptions = {}\n) {\n const uniqueDeps = [...new Set(deps)].filter(Boolean);\n\n if (uniqueDeps.length === 0) {\n return;\n }\n\n const isDev = options.dev ?? false;\n\n if (pm === \"npm\") {\n const args = [\"install\", ...(isDev ? [\"--save-dev\"] : []), ...uniqueDeps];\n await execa(\"npm\", args, { cwd });\n return;\n }\n\n if (pm === \"pnpm\") {\n const args = [\"add\", ...(isDev ? [\"-D\"] : []), ...uniqueDeps];\n await execa(\"pnpm\", args, { cwd });\n return;\n }\n\n if (pm === \"yarn\") {\n const args = [\"add\", ...(isDev ? [\"-D\"] : []), ...uniqueDeps];\n await execa(\"yarn\", args, { cwd });\n return;\n }\n\n if (pm === \"bun\") {\n const args = [\"add\", ...(isDev ? [\"-d\"] : []), ...uniqueDeps];\n await execa(\"bun\", args, { cwd });\n return;\n }\n\n throw new Error(`Unsupported package manager: ${pm}`);\n}\n","import fs from \"fs-extra\";\r\nimport path from \"path\";\r\nimport os from \"os\";\r\n\r\n/**\r\n * Creates or updates .env file with new variables\r\n */\r\nexport const updateEnvFile = async (\r\n cwd: string,\r\n variables: Record<string, string>,\r\n createIfMissing = true\r\n) => {\r\n const envPath = path.join(cwd, \".env\");\r\n\r\n let content = \"\";\r\n if (fs.existsSync(envPath)) {\r\n content = await fs.readFile(envPath, \"utf-8\");\r\n } else if (!createIfMissing) {\r\n return;\r\n }\r\n\r\n let modified = false;\r\n\r\n for (const [key, value] of Object.entries(variables)) {\r\n // Check if key already exists\r\n const regex = new RegExp(`^${key}=`, \"m\");\r\n if (!regex.test(content)) {\r\n // Add newline if content doesn't end with one\r\n if (content && !content.endsWith(\"\\n\")) {\r\n content += os.EOL;\r\n }\r\n content += `${key}=${value}${os.EOL}`;\r\n modified = true;\r\n }\r\n }\r\n\r\n if (modified || !fs.existsSync(envPath)) {\r\n await fs.writeFile(envPath, content);\r\n }\r\n};\r\n\r\n/**\r\n * Updates env.ts to add new schema fields\r\n */\r\nexport const updateEnvSchema = async (\r\n cwd: string,\r\n srcDir: string,\r\n fields: Array<{ name: string; schema: string }>\r\n) => {\r\n const envPath = path.join(cwd, srcDir, \"env.ts\");\r\n\r\n if (!fs.existsSync(envPath)) {\r\n return false;\r\n }\r\n\r\n let content = await fs.readFile(envPath, \"utf-8\");\r\n let modified = false;\r\n\r\n for (const field of fields) {\r\n // Check if field already exists in schema\r\n if (content.includes(`${field.name}:`)) {\r\n continue;\r\n }\r\n\r\n // Find the closing of envSchema z.object({ ... })\r\n // Insert before the closing });\r\n const schemaEndRegex = /(\\n\\s*)(}\\);?\\s*\\n\\s*export const env)/;\r\n const match = content.match(schemaEndRegex);\r\n\r\n if (match) {\r\n const indent = \" \"; // 4 spaces\r\n const newField = `${indent}${field.name}: ${field.schema},\\n`;\r\n content = content.replace(\r\n schemaEndRegex,\r\n `\\n${newField}$1$2`\r\n );\r\n modified = true;\r\n }\r\n }\r\n\r\n if (modified) {\r\n await fs.writeFile(envPath, content);\r\n }\r\n\r\n return modified;\r\n};\r\n\r\n/**\r\n * Creates initial .env file for new projects\r\n */\r\nexport const createInitialEnv = async (cwd: string) => {\r\n const envPath = path.join(cwd, \".env\");\r\n\r\n if (fs.existsSync(envPath)) {\r\n return; // Don't overwrite existing\r\n }\r\n\r\n const content = `# Environment Variables\r\nPORT=3000\r\nNODE_ENV=development\r\n`;\r\n\r\n await fs.writeFile(envPath, content);\r\n};\r\n\r\n/**\r\n * Module-specific env configurations\r\n */\r\nexport const ENV_CONFIGS = {\r\n \"database-pg\": {\r\n envVars: {\r\n DATABASE_URL: \"postgresql://postgres@localhost:5432/mydb\",\r\n },\r\n schemaFields: [\r\n { name: \"DATABASE_URL\", schema: \"z.string().url()\" },\r\n ],\r\n },\r\n \"database-mysql\": {\r\n envVars: {\r\n DATABASE_URL: \"mysql://root@localhost:3306/mydb\",\r\n },\r\n schemaFields: [\r\n { name: \"DATABASE_URL\", schema: \"z.string().url()\" },\r\n ],\r\n },\r\n auth: {\r\n envVars: {\r\n BETTER_AUTH_SECRET: \"your-secret-key-at-least-32-characters-long\",\r\n BETTER_AUTH_URL: \"http://localhost:3000\",\r\n },\r\n schemaFields: [\r\n { name: \"BETTER_AUTH_SECRET\", schema: \"z.string().min(32)\" },\r\n { name: \"BETTER_AUTH_URL\", schema: \"z.string().url()\" },\r\n ],\r\n },\r\n};\r\n","import fs from \"fs-extra\";\nimport path from \"path\";\n\nexport interface ZuroConfig {\n name?: string;\n pm?: string;\n srcDir?: string;\n}\n\nfunction sanitizeConfig(input: unknown): ZuroConfig {\n if (!input || typeof input !== \"object\") {\n return {};\n }\n\n const raw = input as Record<string, unknown>;\n const config: ZuroConfig = {};\n\n if (typeof raw.name === \"string\") {\n config.name = raw.name;\n }\n\n if (typeof raw.pm === \"string\") {\n config.pm = raw.pm;\n }\n\n if (typeof raw.srcDir === \"string\") {\n config.srcDir = raw.srcDir;\n }\n\n return config;\n}\n\nexport function getConfigPath(cwd: string) {\n return path.join(cwd, \"zuro.json\");\n}\n\nexport async function readZuroConfig(cwd: string): Promise<ZuroConfig | null> {\n const configPath = getConfigPath(cwd);\n\n if (!(await fs.pathExists(configPath))) {\n return null;\n }\n\n const raw = await fs.readJson(configPath);\n return sanitizeConfig(raw);\n}\n\nexport async function writeZuroConfig(cwd: string, config: ZuroConfig) {\n const configPath = getConfigPath(cwd);\n await fs.writeJson(configPath, sanitizeConfig(config), { spaces: 2 });\n}\n","import chalk from \"chalk\";\n\nexport function showNonZuroProjectMessage() {\n console.log(chalk.yellow(\"This directory looks like an existing project that wasn't created with Zuro CLI.\"));\n console.log(\"\");\n console.log(chalk.yellow(\"We stopped here because we don't want to make unnecessary changes to your project.\"));\n console.log(\"\");\n console.log(\"Zuro CLI works in:\");\n console.log(\"- a fresh/empty directory, or\");\n console.log(\"- an existing project already managed by Zuro CLI.\");\n}\n","import prompts from \"prompts\";\nimport ora from \"ora\";\nimport path from \"path\";\nimport fs from \"fs-extra\";\nimport { fetchRegistry, fetchFile, RegistryFile } from \"../utils/registry\";\nimport { installDependencies } from \"../utils/pm\";\nimport { resolveDependencies } from \"../utils/dependency\";\nimport { updateEnvFile, updateEnvSchema, ENV_CONFIGS } from \"../utils/env-manager\";\nimport chalk from \"chalk\";\nimport { readZuroConfig } from \"../utils/config\";\nimport { showNonZuroProjectMessage } from \"../utils/project-guard\";\n\nfunction resolveSafeTargetPath(projectRoot: string, srcDir: string, file: RegistryFile) {\n const targetPath = path.resolve(projectRoot, srcDir, file.target);\n const normalizedRoot = path.resolve(projectRoot);\n\n if (targetPath !== normalizedRoot && !targetPath.startsWith(`${normalizedRoot}${path.sep}`)) {\n throw new Error(`Refusing to write outside project directory: ${file.target}`);\n }\n\n return targetPath;\n}\n\n/**\n * Modifies app.ts to include error handler middleware\n */\nasync function injectErrorHandler(projectRoot: string, srcDir: string): Promise<boolean> {\n const appPath = path.join(projectRoot, srcDir, \"app.ts\");\n\n if (!fs.existsSync(appPath)) {\n return false;\n }\n\n let content = await fs.readFile(appPath, \"utf-8\");\n\n if (content.includes(\"errorHandler\")) {\n return true;\n }\n\n const errorImport = `import { errorHandler, notFoundHandler } from \"./middleware/error-handler\";`;\n\n const importRegex = /^import .+ from .+;?\\s*$/gm;\n let lastImportIndex = 0;\n let match;\n\n while ((match = importRegex.exec(content)) !== null) {\n lastImportIndex = match.index + match[0].length;\n }\n\n if (lastImportIndex > 0) {\n content = content.slice(0, lastImportIndex) + `\\n${errorImport}` + content.slice(lastImportIndex);\n }\n\n const errorSetup = `\\n// Error handling (must be last)\\napp.use(notFoundHandler);\\napp.use(errorHandler);\\n`;\n const exportMatch = content.match(/export default app;?\\s*$/m);\n if (exportMatch && exportMatch.index !== undefined) {\n content = content.slice(0, exportMatch.index) + errorSetup + \"\\n\" + content.slice(exportMatch.index);\n }\n\n await fs.writeFile(appPath, content);\n return true;\n}\n\n/**\n * Modifies app.ts to include auth routes\n */\nasync function injectAuthRoutes(projectRoot: string, srcDir: string): Promise<boolean> {\n const appPath = path.join(projectRoot, srcDir, \"app.ts\");\n\n if (!fs.existsSync(appPath)) {\n return false;\n }\n\n let content = await fs.readFile(appPath, \"utf-8\");\n\n if (content.includes(\"routes/auth.routes\")) {\n return true;\n }\n\n const authImport = `import authRoutes from \"./routes/auth.routes\";`;\n const userImport = `import userRoutes from \"./routes/user.routes\";`;\n const routeSetup = `\\n// Auth routes\\napp.use(authRoutes);\\napp.use(\"/api/users\", userRoutes);\\n`;\n\n const importRegex = /^import .+ from .+;?\\s*$/gm;\n let lastImportIndex = 0;\n let match;\n\n while ((match = importRegex.exec(content)) !== null) {\n lastImportIndex = match.index + match[0].length;\n }\n\n if (lastImportIndex > 0) {\n content = content.slice(0, lastImportIndex) + `\\n${authImport}\\n${userImport}` + content.slice(lastImportIndex);\n }\n\n const exportMatch = content.match(/export default app;?\\s*$/m);\n if (exportMatch && exportMatch.index !== undefined) {\n content = content.slice(0, exportMatch.index) + routeSetup + \"\\n\" + content.slice(exportMatch.index);\n }\n\n await fs.writeFile(appPath, content);\n return true;\n}\n\nexport const add = async (moduleName: string) => {\n const projectRoot = process.cwd();\n const projectConfig = await readZuroConfig(projectRoot);\n if (!projectConfig) {\n showNonZuroProjectMessage();\n return;\n }\n let srcDir = projectConfig.srcDir || \"src\";\n\n let customDbUrl: string | undefined;\n\n const DEFAULT_URLS = {\n \"database-pg\": \"postgresql://root@localhost:5432/mydb\",\n \"database-mysql\": \"mysql://root@localhost:3306/mydb\",\n };\n\n if (moduleName === \"database\") {\n const variantResponse = await prompts({\n type: \"select\",\n name: \"variant\",\n message: \"Which database dialect?\",\n choices: [\n { title: \"PostgreSQL\", value: \"database-pg\" },\n { title: \"MySQL\", value: \"database-mysql\" },\n ],\n });\n\n if (!variantResponse.variant) {\n process.exit(0);\n }\n\n moduleName = variantResponse.variant;\n\n const defaultUrl = DEFAULT_URLS[moduleName as keyof typeof DEFAULT_URLS];\n console.log(chalk.dim(` Tip: Leave blank to use ${defaultUrl}\\n`));\n\n const urlResponse = await prompts({\n type: \"text\",\n name: \"dbUrl\",\n message: \"Database URL\",\n initial: \"\",\n });\n customDbUrl = urlResponse.dbUrl?.trim() || defaultUrl;\n }\n\n if ((moduleName === \"database-pg\" || moduleName === \"database-mysql\") && customDbUrl === undefined) {\n const defaultUrl = DEFAULT_URLS[moduleName as keyof typeof DEFAULT_URLS];\n console.log(chalk.dim(` Tip: Leave blank to use ${defaultUrl}\\n`));\n\n const response = await prompts({\n type: \"text\",\n name: \"dbUrl\",\n message: \"Database URL\",\n initial: \"\",\n });\n customDbUrl = response.dbUrl?.trim() || defaultUrl;\n }\n\n const spinner = ora(`Checking registry for ${moduleName}...`).start();\n\n try {\n const registryContext = await fetchRegistry();\n const module = registryContext.manifest.modules[moduleName];\n\n if (!module) {\n spinner.fail(`Module '${moduleName}' not found.`);\n return;\n }\n\n spinner.succeed(`Found module: ${chalk.cyan(moduleName)}`);\n\n const moduleDeps = module.moduleDependencies || [];\n await resolveDependencies(moduleDeps, projectRoot);\n\n spinner.start(\"Installing dependencies...\");\n\n let pm = \"npm\";\n if (fs.existsSync(path.join(projectRoot, \"pnpm-lock.yaml\"))) {\n pm = \"pnpm\";\n } else if (fs.existsSync(path.join(projectRoot, \"bun.lockb\"))) {\n pm = \"bun\";\n } else if (fs.existsSync(path.join(projectRoot, \"yarn.lock\"))) {\n pm = \"yarn\";\n }\n\n await installDependencies(pm, module.dependencies || [], projectRoot);\n await installDependencies(pm, module.devDependencies || [], projectRoot, { dev: true });\n\n spinner.succeed(\"Dependencies installed\");\n\n spinner.start(\"Scaffolding files...\");\n\n for (const file of module.files) {\n const content = await fetchFile(file.path, {\n baseUrl: registryContext.fileBaseUrl,\n expectedSha256: file.sha256,\n expectedSize: file.size,\n });\n\n const targetPath = resolveSafeTargetPath(projectRoot, srcDir, file);\n\n await fs.ensureDir(path.dirname(targetPath));\n await fs.writeFile(targetPath, content);\n }\n\n spinner.succeed(\"Files generated\");\n\n if (moduleName === \"auth\") {\n spinner.start(\"Configuring routes in app.ts...\");\n const injected = await injectAuthRoutes(projectRoot, srcDir);\n if (injected) {\n spinner.succeed(\"Routes configured in app.ts\");\n } else {\n spinner.warn(\"Could not find app.ts - routes need manual setup\");\n }\n }\n\n if (moduleName === \"error-handler\") {\n spinner.start(\"Configuring error handler in app.ts...\");\n const injected = await injectErrorHandler(projectRoot, srcDir);\n if (injected) {\n spinner.succeed(\"Error handler configured in app.ts\");\n } else {\n spinner.warn(\"Could not find app.ts - error handler needs manual setup\");\n }\n }\n\n const envConfig = ENV_CONFIGS[moduleName as keyof typeof ENV_CONFIGS];\n if (envConfig) {\n spinner.start(\"Updating environment configuration...\");\n\n const envVars: Record<string, string> = { ...envConfig.envVars };\n if (customDbUrl && (moduleName === \"database-pg\" || moduleName === \"database-mysql\")) {\n envVars.DATABASE_URL = customDbUrl;\n }\n\n await updateEnvFile(projectRoot, envVars);\n await updateEnvSchema(projectRoot, srcDir, envConfig.schemaFields);\n\n spinner.succeed(\"Environment configured\");\n }\n\n console.log(chalk.green(`\\n✔ ${moduleName} added successfully!\\n`));\n\n if (moduleName === \"auth\") {\n console.log(chalk.bold(\"📋 Next Steps:\\n\"));\n console.log(chalk.yellow(\"1. Update your .env file:\"));\n console.log(\n chalk.dim(\" We added placeholder values. Update BETTER_AUTH_SECRET with a secure key.\\n\")\n );\n console.log(chalk.yellow(\"2. Run database migrations:\"));\n console.log(chalk.cyan(\" npx drizzle-kit generate\"));\n console.log(chalk.cyan(\" npx drizzle-kit migrate\\n\"));\n console.log(chalk.yellow(\"3. Available endpoints:\"));\n console.log(chalk.dim(\" POST /auth/sign-up/email - Register\"));\n console.log(chalk.dim(\" POST /auth/sign-in/email - Login\"));\n console.log(chalk.dim(\" POST /auth/sign-out - Logout\"));\n console.log(chalk.dim(\" GET /api/users/me - Current user\\n\"));\n } else if (moduleName === \"error-handler\") {\n console.log(chalk.bold(\"📋 Usage:\\n\"));\n console.log(chalk.yellow(\"Throw errors in your controllers:\"));\n console.log(chalk.dim(\" ─────────────────────────────────────\"));\n console.log(chalk.white(` import { UnauthorizedError, NotFoundError } from \"./lib/errors\";`));\n console.log(\"\");\n console.log(chalk.white(` throw new UnauthorizedError(\"Invalid credentials\");`));\n console.log(chalk.white(` throw new NotFoundError(\"User not found\");`));\n console.log(chalk.dim(\" ─────────────────────────────────────\\n\"));\n console.log(chalk.yellow(\"Available error classes:\"));\n console.log(chalk.dim(\" BadRequestError (400)\"));\n console.log(chalk.dim(\" UnauthorizedError (401)\"));\n console.log(chalk.dim(\" ForbiddenError (403)\"));\n console.log(chalk.dim(\" NotFoundError (404)\"));\n console.log(chalk.dim(\" ConflictError (409)\"));\n console.log(chalk.dim(\" ValidationError (422)\"));\n console.log(chalk.dim(\" InternalServerError (500)\\n\"));\n console.log(chalk.yellow(\"Wrap async handlers:\"));\n console.log(chalk.dim(\" ─────────────────────────────────────\"));\n console.log(chalk.white(` import { asyncHandler } from \"./middleware/error-handler\";`));\n console.log(\"\");\n console.log(chalk.white(` router.get(\"/users\", asyncHandler(async (req, res) => {`));\n console.log(chalk.white(\" // errors auto-caught\"));\n console.log(chalk.white(\" }));\"));\n console.log(chalk.dim(\" ─────────────────────────────────────\\n\"));\n } else if (moduleName.includes(\"database\")) {\n console.log(chalk.bold(\"📋 Next Steps:\\n\"));\n let stepNum = 1;\n\n if (!customDbUrl) {\n console.log(chalk.yellow(`${stepNum}. Update DATABASE_URL in .env:`));\n console.log(\n chalk.dim(\" We added a placeholder. Update with your actual database credentials.\\n\")\n );\n stepNum++;\n }\n\n console.log(chalk.yellow(`${stepNum}. Create schemas in src/db/schema/:`));\n console.log(chalk.dim(\" Add table files and export from index.ts\\n\"));\n stepNum++;\n\n console.log(chalk.yellow(`${stepNum}. Run migrations:`));\n console.log(chalk.cyan(\" npx drizzle-kit generate\"));\n console.log(chalk.cyan(\" npx drizzle-kit migrate\\n\"));\n }\n } catch (error) {\n spinner.fail(`Failed to add module: ${(error as Error).message}`);\n }\n};\n","import { add } from \"../commands/add\";\nimport { readZuroConfig } from \"./config\";\nimport fs from \"fs-extra\";\nimport path from \"path\";\nimport chalk from \"chalk\";\n\n// Signature files to check if a Zuro module is installed\nconst BLOCK_SIGNATURES: Record<string, string> = {\n core: \"env.ts\",\n \"database-pg\": \"db/index.ts\",\n \"database-mysql\": \"db/index.ts\",\n validator: \"middleware/validate.ts\",\n \"error-handler\": \"lib/errors.ts\",\n logger: \"lib/logger.ts\",\n auth: \"lib/auth.ts\",\n};\n\n/**\n * Resolves Zuro module dependencies (NOT npm packages).\n * Only handles module dependencies like \"core\", \"database\", \"validator\", \"auth\".\n */\nexport const resolveDependencies = async (\n moduleDependencies: string[] | undefined,\n cwd: string\n) => {\n if (!moduleDependencies || moduleDependencies.length === 0) {\n return;\n }\n\n const config = await readZuroConfig(cwd);\n const srcDir = config?.srcDir || \"src\";\n\n for (const dep of moduleDependencies) {\n if (dep === \"database\") {\n const pgExists = fs.existsSync(path.join(cwd, srcDir, BLOCK_SIGNATURES[\"database-pg\"]));\n const mysqlExists = fs.existsSync(path.join(cwd, srcDir, BLOCK_SIGNATURES[\"database-mysql\"]));\n\n if (pgExists || mysqlExists) {\n continue;\n }\n\n console.log(chalk.blue(`ℹ Dependency '${dep}' is missing. Triggering install...`));\n await add(\"database\");\n continue;\n }\n\n const signature = BLOCK_SIGNATURES[dep];\n if (!signature) {\n continue;\n }\n\n if (fs.existsSync(path.join(cwd, srcDir, signature))) {\n continue;\n }\n\n console.log(chalk.blue(`ℹ Installing missing dependency: ${dep}...`));\n await add(dep);\n }\n};\n"],"mappings":"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","names":["chalk","fs","path","fs","path","fs","path","path","fs","chalk","prompts","ora","path","fs","fs","path","chalk","chalk","resolveSafeTargetPath","path","fs","prompts","chalk","ora"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/commands/init.ts","../src/utils/registry.ts","../src/utils/pm.ts","../src/utils/env-manager.ts","../src/utils/config.ts","../src/utils/project-guard.ts","../src/commands/add.ts","../src/utils/dependency.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { Command } from \"commander\";\nimport { init } from \"./commands/init\";\nimport { add } from \"./commands/add\";\n\nconst program = new Command();\n\nprogram\n .name(\"zuro-cli\")\n .description(\"Zuro CLI tool\")\n .version(\"0.0.1\");\n\nprogram\n .command(\"init\")\n .description(\"Initialize a new Zuro project\")\n .action(init);\n\nprogram\n .command(\"add <module>\")\n .description(\"Add a module to your project\")\n .action(add);\n\nprogram.parse(process.argv);\n","import ora from \"ora\";\nimport chalk from \"chalk\";\nimport fs from \"fs-extra\";\nimport path from \"path\";\nimport prompts from \"prompts\";\nimport { fetchRegistry, fetchFile, RegistryFile } from \"../utils/registry\";\nimport { initPackageJson, installDependencies, ensurePackageManagerAvailable } from \"../utils/pm\";\nimport { createInitialEnv } from \"../utils/env-manager\";\nimport { readZuroConfig, writeZuroConfig } from \"../utils/config\";\nimport { showNonZuroProjectMessage } from \"../utils/project-guard\";\nimport type { ZuroConfig } from \"../utils/config\";\n\nfunction resolveSafeTargetPath(projectRoot: string, srcDir: string, file: RegistryFile) {\n const relativeTargetPath = path.join(srcDir, file.target);\n const targetPath = path.resolve(projectRoot, relativeTargetPath);\n const normalizedRoot = path.resolve(projectRoot);\n\n if (targetPath !== normalizedRoot && !targetPath.startsWith(`${normalizedRoot}${path.sep}`)) {\n throw new Error(`Refusing to write outside project directory: ${file.target}`);\n }\n\n return {\n relativeTargetPath,\n targetPath,\n };\n}\n\nasync function ensureSafeTargetDirectory(targetDir: string, cwd: string, projectName: string) {\n await fs.ensureDir(targetDir);\n const entries = await fs.readdir(targetDir);\n\n if (entries.length === 0) {\n return true;\n }\n\n const isCurrentFolder = targetDir === cwd;\n const response = await prompts({\n type: \"confirm\",\n name: \"proceed\",\n message: isCurrentFolder\n ? `Current folder '${projectName}' is not empty. Continue anyway?`\n : `Target folder '${projectName}' already exists and is not empty. Continue anyway?`,\n initial: false,\n });\n\n return response.proceed === true;\n}\n\nexport async function init() {\n const cwd = process.cwd();\n const isExistingProject = await fs.pathExists(path.join(cwd, \"package.json\"));\n const existingZuroConfig = await readZuroConfig(cwd);\n\n if (isExistingProject && !existingZuroConfig) {\n showNonZuroProjectMessage();\n return;\n }\n\n let targetDir = cwd;\n let pm = \"npm\";\n let srcDir = \"src\";\n let projectName = path.basename(cwd);\n\n if (isExistingProject) {\n console.log(chalk.blue(\"ℹ Existing project detected.\"));\n\n projectName = path.basename(cwd);\n\n if (await fs.pathExists(path.join(cwd, \"pnpm-lock.yaml\"))) {\n pm = \"pnpm\";\n } else if (await fs.pathExists(path.join(cwd, \"bun.lockb\"))) {\n pm = \"bun\";\n } else if (await fs.pathExists(path.join(cwd, \"yarn.lock\"))) {\n pm = \"yarn\";\n }\n\n const response = await prompts({\n type: \"text\",\n name: \"srcDir\",\n message: \"Where is your source code located?\",\n initial: \"src\",\n });\n\n srcDir = response.srcDir || \"src\";\n } else {\n console.log(chalk.dim(` Tip: Leave blank to use current folder (${path.basename(cwd)})\\n`));\n\n const response = await prompts([\n {\n type: \"text\",\n name: \"path\",\n message: \"Project name (blank for current folder)\",\n initial: \"\",\n },\n {\n type: \"select\",\n name: \"pm\",\n message: \"Package Manager?\",\n choices: [\n { title: \"npm\", value: \"npm\" },\n { title: \"pnpm\", value: \"pnpm\" },\n { title: \"bun\", value: \"bun\" },\n ],\n initial: 0,\n },\n ]);\n\n if (response.pm === undefined) {\n console.log(chalk.red(\"Operation cancelled.\"));\n return;\n }\n\n pm = response.pm;\n srcDir = \"src\";\n\n if (!response.path || response.path.trim() === \"\") {\n projectName = path.basename(cwd);\n targetDir = cwd;\n console.log(chalk.blue(`ℹ Using current folder: ${projectName}`));\n } else {\n projectName = response.path.trim();\n targetDir = path.resolve(cwd, projectName);\n }\n\n const isSafeTarget = await ensureSafeTargetDirectory(targetDir, cwd, projectName);\n if (!isSafeTarget) {\n console.log(chalk.red(\"Operation cancelled.\"));\n return;\n }\n }\n\n const existingConfig = targetDir === cwd ? existingZuroConfig : await readZuroConfig(targetDir);\n\n const zuroConfig: ZuroConfig = {\n name: projectName,\n pm,\n srcDir: srcDir || existingConfig?.srcDir || \"src\",\n };\n\n const spinner = ora(\"Connecting to Zuro Registry...\").start();\n let currentStep = \"package manager preflight\";\n\n try {\n spinner.text = `Checking ${pm} availability...`;\n await ensurePackageManagerAvailable(pm);\n\n currentStep = \"registry fetch\";\n spinner.text = \"Connecting to Zuro Registry...\";\n const registryContext = await fetchRegistry();\n\n const coreModule = registryContext.manifest.modules.core;\n\n if (!coreModule) {\n spinner.fail(\"Core module not found in registry.\");\n return;\n }\n\n currentStep = \"project initialization\";\n spinner.text = \"Initializing project...\";\n\n const hasPackageJson = await fs.pathExists(path.join(targetDir, \"package.json\"));\n if (!hasPackageJson) {\n await initPackageJson(targetDir, true, projectName, srcDir);\n }\n\n currentStep = \"dependency installation\";\n spinner.text = `Installing dependencies using ${pm}...`;\n\n let runtimeDeps: string[] = [];\n let devDeps: string[] = [];\n\n if (isExistingProject) {\n const safeDeps = [\"zod\", \"dotenv\"];\n const coreDeps = coreModule.dependencies || [];\n runtimeDeps = coreDeps.filter((dependency) => safeDeps.includes(dependency));\n devDeps = coreModule.devDependencies || [];\n } else {\n runtimeDeps = coreModule.dependencies || [];\n devDeps = coreModule.devDependencies || [];\n }\n\n await installDependencies(pm, runtimeDeps, targetDir);\n await installDependencies(pm, devDeps, targetDir, { dev: true });\n\n currentStep = \"module file generation\";\n spinner.text = \"Fetching core module files...\";\n\n for (const file of coreModule.files) {\n const { relativeTargetPath, targetPath } = resolveSafeTargetPath(targetDir, srcDir, file);\n const fileName = path.basename(targetPath);\n\n if (isExistingProject) {\n if (fileName === \"app.ts\" || fileName === \"server.ts\") {\n continue;\n }\n\n const relativeParts = relativeTargetPath.split(path.sep);\n const isSafe = fileName === \"env.ts\" || relativeParts.includes(\"lib\");\n if (!isSafe) {\n continue;\n }\n }\n\n const content = await fetchFile(file.path, {\n baseUrl: registryContext.fileBaseUrl,\n expectedSha256: file.sha256,\n expectedSize: file.size,\n });\n\n await fs.ensureDir(path.dirname(targetPath));\n await fs.writeFile(targetPath, content);\n }\n\n currentStep = \"environment file setup\";\n await createInitialEnv(targetDir);\n\n currentStep = \"config write\";\n await writeZuroConfig(targetDir, zuroConfig);\n\n spinner.succeed(chalk.green(\"Project initialized successfully!\"));\n\n console.log(`\\n${chalk.bold(\"Next steps:\")}`);\n if (targetDir !== cwd) {\n console.log(chalk.cyan(` cd ${projectName}`));\n }\n console.log(chalk.cyan(` ${pm} run dev`));\n console.log(`\\n${chalk.dim(\"Add modules: zuro-cli add database, zuro-cli add auth\")}`);\n } catch (error) {\n spinner.fail(chalk.red(`Failed during ${currentStep}.`));\n const errorMessage = error instanceof Error ? error.message : String(error);\n console.error(chalk.red(errorMessage));\n console.log(`\\n${chalk.bold(\"Retry:\")}`);\n if (targetDir !== cwd) {\n console.log(chalk.cyan(` cd ${projectName}`));\n }\n console.log(chalk.cyan(\" npx zuro-cli init\"));\n }\n}\n","import { createHash } from \"node:crypto\";\n\nconst DEFAULT_REGISTRY_BASE_URL = \"https://registry.devbybriyan.com\";\nconst DEFAULT_REGISTRY_ENTRY_URL = `${DEFAULT_REGISTRY_BASE_URL}/channels/stable.json`;\nconst REGISTRY_ENV_VAR = \"ZURO_REGISTRY_URL\";\nconst REQUEST_TIMEOUT_MS = 8000;\nconst MAX_RETRIES = 2;\n\nexport interface RegistryFile {\n path: string;\n target: string;\n type: string;\n sha256?: string;\n size?: number;\n}\n\nexport interface RegistryModule {\n type: string;\n files: RegistryFile[];\n moduleDependencies?: string[];\n dependencies?: string[];\n devDependencies?: string[];\n}\n\nexport interface RegistryManifest {\n schemaVersion?: number;\n status?: string;\n templateVersion?: string;\n generatedAt?: string;\n modules: Record<string, RegistryModule>;\n}\n\ninterface RegistryChannelPointer {\n schemaVersion?: number;\n channel?: string;\n templateVersion?: string;\n generatedAt?: string;\n indexPath?: string;\n indexUrl?: string;\n}\n\nexport interface RegistryContext {\n manifest: RegistryManifest;\n manifestUrl: string;\n fileBaseUrl: string;\n}\n\ninterface FetchFileOptions {\n baseUrl: string;\n expectedSha256?: string;\n expectedSize?: number;\n}\n\nexport function getRegistryUrl() {\n return resolveRegistryEntryUrl();\n}\n\nfunction withTrailingSlash(url: string) {\n return url.endsWith(\"/\") ? url : `${url}/`;\n}\n\nfunction resolveRegistryEntryUrl() {\n const override = process.env[REGISTRY_ENV_VAR]?.trim();\n\n if (!override) {\n return DEFAULT_REGISTRY_ENTRY_URL;\n }\n\n let parsed: URL;\n\n try {\n parsed = new URL(override);\n } catch {\n throw new Error(\n `Invalid ${REGISTRY_ENV_VAR} value '${override}'. Expected a valid http(s) URL.`\n );\n }\n\n if (parsed.pathname.endsWith(\".json\")) {\n return parsed.toString();\n }\n\n return new URL(\"channels/stable.json\", withTrailingSlash(parsed.toString())).toString();\n}\n\nfunction isRegistryManifest(data: unknown): data is RegistryManifest {\n if (!data || typeof data !== \"object\") {\n return false;\n }\n\n const candidate = data as Partial<RegistryManifest>;\n return !!candidate.modules && typeof candidate.modules === \"object\";\n}\n\nfunction isChannelPointer(data: unknown): data is RegistryChannelPointer {\n if (!data || typeof data !== \"object\") {\n return false;\n }\n\n const candidate = data as Partial<RegistryChannelPointer>;\n return typeof candidate.indexPath === \"string\" || typeof candidate.indexUrl === \"string\";\n}\n\nfunction delay(ms: number) {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nasync function fetchWithRetry(url: string): Promise<Response> {\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), REQUEST_TIMEOUT_MS);\n\n try {\n const response = await fetch(url, {\n headers: { Accept: \"application/json, text/plain, */*\" },\n signal: controller.signal,\n });\n\n if (response.ok) {\n return response;\n }\n\n const shouldRetry = response.status >= 500 && attempt < MAX_RETRIES;\n if (shouldRetry) {\n await delay(250 * (attempt + 1));\n continue;\n }\n\n throw new Error(`Request failed (${response.status} ${response.statusText}) for ${url}`);\n } catch (error) {\n lastError = error;\n\n if (attempt === MAX_RETRIES) {\n break;\n }\n\n await delay(250 * (attempt + 1));\n } finally {\n clearTimeout(timeout);\n }\n }\n\n if (lastError instanceof Error) {\n throw lastError;\n }\n\n throw new Error(`Failed to fetch ${url}`);\n}\n\nasync function fetchJson<T>(url: string): Promise<{ data: T; resolvedUrl: string }> {\n const response = await fetchWithRetry(url);\n const data = (await response.json()) as T;\n\n return {\n data,\n resolvedUrl: response.url || url,\n };\n}\n\nfunction resolveManifestUrl(pointer: RegistryChannelPointer, pointerUrl: string): string {\n const explicit = pointer.indexUrl || pointer.indexPath;\n\n if (!explicit) {\n throw new Error(\"Registry channel pointer is missing indexUrl/indexPath\");\n }\n\n return new URL(explicit, pointerUrl).toString();\n}\n\nexport async function fetchRegistry(): Promise<RegistryContext> {\n const registryEntryUrl = resolveRegistryEntryUrl();\n let entry: { data: unknown; resolvedUrl: string };\n\n try {\n entry = await fetchJson<unknown>(registryEntryUrl);\n } catch (error) {\n throw new Error(\n `Unable to fetch registry from ${registryEntryUrl}. For local testing set ${REGISTRY_ENV_VAR}=http://127.0.0.1:8787.`,\n { cause: error as Error }\n );\n }\n\n if (isRegistryManifest(entry.data)) {\n return {\n manifest: entry.data,\n manifestUrl: entry.resolvedUrl,\n fileBaseUrl: withTrailingSlash(new URL(\".\", entry.resolvedUrl).toString()),\n };\n }\n\n if (!isChannelPointer(entry.data)) {\n throw new Error(\n `Invalid registry payload at ${registryEntryUrl}. Expected manifest or channel pointer.`\n );\n }\n\n const manifestUrl = resolveManifestUrl(entry.data, entry.resolvedUrl);\n const manifestResult = await fetchJson<unknown>(manifestUrl);\n\n if (!isRegistryManifest(manifestResult.data)) {\n throw new Error(`Invalid manifest payload at ${manifestUrl}.`);\n }\n\n return {\n manifest: manifestResult.data,\n manifestUrl: manifestResult.resolvedUrl,\n fileBaseUrl: withTrailingSlash(new URL(\".\", manifestResult.resolvedUrl).toString()),\n };\n}\n\nexport async function fetchFile(filePath: string, options: FetchFileOptions) {\n const normalizedPath = filePath.replace(/^\\//, \"\");\n const fileUrl = new URL(normalizedPath, withTrailingSlash(options.baseUrl)).toString();\n const response = await fetchWithRetry(fileUrl);\n const content = await response.text();\n\n if (typeof options.expectedSize === \"number\") {\n const actualSize = Buffer.byteLength(content, \"utf8\");\n if (actualSize !== options.expectedSize) {\n throw new Error(\n `Size mismatch for ${filePath}. Expected ${options.expectedSize}, got ${actualSize}.`\n );\n }\n }\n\n if (options.expectedSha256) {\n const actualSha256 = createHash(\"sha256\").update(content, \"utf8\").digest(\"hex\");\n if (actualSha256 !== options.expectedSha256) {\n throw new Error(\n `Checksum mismatch for ${filePath}. Expected ${options.expectedSha256}, got ${actualSha256}.`\n );\n }\n }\n\n return content;\n}\n","import fs from \"fs-extra\";\nimport path from \"path\";\nimport { execa } from \"execa\";\n\nfunction normalizePackageName(name: string) {\n const normalized = name\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9._-]/g, \"-\")\n .replace(/-+/g, \"-\")\n .replace(/^[._-]+|[._-]+$/g, \"\");\n\n return normalized || \"zuro-app\";\n}\n\nexport async function ensurePackageManagerAvailable(pm: string) {\n try {\n await execa(pm, [\"--version\"], { stdio: \"ignore\" });\n } catch {\n throw new Error(\n `Package manager '${pm}' is not installed or not available in PATH. Install it or choose npm.`\n );\n }\n}\n\nexport async function initPackageJson(\n cwd: string,\n force: boolean = false,\n packageName = \"zuro-app\",\n srcDir = \"src\"\n) {\n const pkgPath = path.join(cwd, \"package.json\");\n if (force || !await fs.pathExists(pkgPath)) {\n await fs.writeJson(pkgPath, {\n name: normalizePackageName(packageName),\n version: \"0.0.1\",\n private: true,\n scripts: {\n \"dev\": `tsx watch ${srcDir}/server.ts`,\n \"build\": \"tsc\",\n \"start\": \"node dist/server.js\"\n }\n }, { spaces: 2 });\n }\n}\n\ninterface InstallOptions {\n dev?: boolean;\n}\n\nexport async function installDependencies(\n pm: string,\n deps: string[],\n cwd: string,\n options: InstallOptions = {}\n) {\n const uniqueDeps = [...new Set(deps)].filter(Boolean);\n\n if (uniqueDeps.length === 0) {\n return;\n }\n\n const isDev = options.dev ?? false;\n\n if (pm === \"npm\") {\n const args = [\"install\", ...(isDev ? [\"--save-dev\"] : []), ...uniqueDeps];\n await execa(\"npm\", args, { cwd });\n return;\n }\n\n if (pm === \"pnpm\") {\n const args = [\"add\", ...(isDev ? [\"-D\"] : []), ...uniqueDeps];\n await execa(\"pnpm\", args, { cwd });\n return;\n }\n\n if (pm === \"yarn\") {\n const args = [\"add\", ...(isDev ? [\"-D\"] : []), ...uniqueDeps];\n await execa(\"yarn\", args, { cwd });\n return;\n }\n\n if (pm === \"bun\") {\n const args = [\"add\", ...(isDev ? [\"-d\"] : []), ...uniqueDeps];\n await execa(\"bun\", args, { cwd });\n return;\n }\n\n throw new Error(`Unsupported package manager: ${pm}`);\n}\n","import fs from \"fs-extra\";\r\nimport path from \"path\";\r\nimport os from \"os\";\r\n\r\n/**\r\n * Creates or updates .env file with new variables\r\n */\r\nexport const updateEnvFile = async (\r\n cwd: string,\r\n variables: Record<string, string>,\r\n createIfMissing = true\r\n) => {\r\n const envPath = path.join(cwd, \".env\");\r\n\r\n let content = \"\";\r\n if (fs.existsSync(envPath)) {\r\n content = await fs.readFile(envPath, \"utf-8\");\r\n } else if (!createIfMissing) {\r\n return;\r\n }\r\n\r\n let modified = false;\r\n\r\n for (const [key, value] of Object.entries(variables)) {\r\n // Check if key already exists\r\n const regex = new RegExp(`^${key}=`, \"m\");\r\n if (!regex.test(content)) {\r\n // Add newline if content doesn't end with one\r\n if (content && !content.endsWith(\"\\n\")) {\r\n content += os.EOL;\r\n }\r\n content += `${key}=${value}${os.EOL}`;\r\n modified = true;\r\n }\r\n }\r\n\r\n if (modified || !fs.existsSync(envPath)) {\r\n await fs.writeFile(envPath, content);\r\n }\r\n};\r\n\r\n/**\r\n * Updates env.ts to add new schema fields\r\n */\r\nexport const updateEnvSchema = async (\r\n cwd: string,\r\n srcDir: string,\r\n fields: Array<{ name: string; schema: string }>\r\n) => {\r\n const envPath = path.join(cwd, srcDir, \"env.ts\");\r\n\r\n if (!fs.existsSync(envPath)) {\r\n return false;\r\n }\r\n\r\n let content = await fs.readFile(envPath, \"utf-8\");\r\n let modified = false;\r\n\r\n for (const field of fields) {\r\n // Check if field already exists in schema\r\n if (content.includes(`${field.name}:`)) {\r\n continue;\r\n }\r\n\r\n // Find the closing of envSchema z.object({ ... })\r\n // Insert before the closing });\r\n const schemaEndRegex = /(\\n\\s*)(}\\);?\\s*\\n\\s*export const env)/;\r\n const match = content.match(schemaEndRegex);\r\n\r\n if (match) {\r\n const indent = \" \"; // 4 spaces\r\n const newField = `${indent}${field.name}: ${field.schema},\\n`;\r\n content = content.replace(\r\n schemaEndRegex,\r\n `\\n${newField}$1$2`\r\n );\r\n modified = true;\r\n }\r\n }\r\n\r\n if (modified) {\r\n await fs.writeFile(envPath, content);\r\n }\r\n\r\n return modified;\r\n};\r\n\r\n/**\r\n * Creates initial .env file for new projects\r\n */\r\nexport const createInitialEnv = async (cwd: string) => {\r\n const envPath = path.join(cwd, \".env\");\r\n\r\n if (fs.existsSync(envPath)) {\r\n return; // Don't overwrite existing\r\n }\r\n\r\n const content = `# Environment Variables\r\nPORT=3000\r\nNODE_ENV=development\r\n`;\r\n\r\n await fs.writeFile(envPath, content);\r\n};\r\n\r\n/**\r\n * Module-specific env configurations\r\n */\r\nexport const ENV_CONFIGS = {\r\n \"database-pg\": {\r\n envVars: {\r\n DATABASE_URL: \"postgresql://postgres@localhost:5432/mydb\",\r\n },\r\n schemaFields: [\r\n { name: \"DATABASE_URL\", schema: \"z.string().url()\" },\r\n ],\r\n },\r\n \"database-mysql\": {\r\n envVars: {\r\n DATABASE_URL: \"mysql://root@localhost:3306/mydb\",\r\n },\r\n schemaFields: [\r\n { name: \"DATABASE_URL\", schema: \"z.string().url()\" },\r\n ],\r\n },\r\n auth: {\r\n envVars: {\r\n BETTER_AUTH_SECRET: \"your-secret-key-at-least-32-characters-long\",\r\n BETTER_AUTH_URL: \"http://localhost:3000\",\r\n },\r\n schemaFields: [\r\n { name: \"BETTER_AUTH_SECRET\", schema: \"z.string().min(32)\" },\r\n { name: \"BETTER_AUTH_URL\", schema: \"z.string().url()\" },\r\n ],\r\n },\r\n};\r\n","import fs from \"fs-extra\";\nimport path from \"path\";\n\nexport interface ZuroConfig {\n name?: string;\n pm?: string;\n srcDir?: string;\n}\n\nfunction sanitizeConfig(input: unknown): ZuroConfig {\n if (!input || typeof input !== \"object\") {\n return {};\n }\n\n const raw = input as Record<string, unknown>;\n const config: ZuroConfig = {};\n\n if (typeof raw.name === \"string\") {\n config.name = raw.name;\n }\n\n if (typeof raw.pm === \"string\") {\n config.pm = raw.pm;\n }\n\n if (typeof raw.srcDir === \"string\") {\n config.srcDir = raw.srcDir;\n }\n\n return config;\n}\n\nexport function getConfigPath(cwd: string) {\n return path.join(cwd, \"zuro.json\");\n}\n\nexport async function readZuroConfig(cwd: string): Promise<ZuroConfig | null> {\n const configPath = getConfigPath(cwd);\n\n if (!(await fs.pathExists(configPath))) {\n return null;\n }\n\n const raw = await fs.readJson(configPath);\n return sanitizeConfig(raw);\n}\n\nexport async function writeZuroConfig(cwd: string, config: ZuroConfig) {\n const configPath = getConfigPath(cwd);\n await fs.writeJson(configPath, sanitizeConfig(config), { spaces: 2 });\n}\n","import chalk from \"chalk\";\n\nexport function showNonZuroProjectMessage() {\n console.log(chalk.yellow(\"This directory looks like an existing project that wasn't created with Zuro CLI.\"));\n console.log(\"\");\n console.log(chalk.yellow(\"We stopped here because we don't want to make unnecessary changes to your project.\"));\n console.log(\"\");\n console.log(\"Zuro CLI works in:\");\n console.log(\"- a fresh/empty directory, or\");\n console.log(\"- an existing project already managed by Zuro CLI.\");\n}\n","import prompts from \"prompts\";\nimport ora from \"ora\";\nimport path from \"path\";\nimport fs from \"fs-extra\";\nimport { fetchRegistry, fetchFile, RegistryFile } from \"../utils/registry\";\nimport { installDependencies } from \"../utils/pm\";\nimport { resolveDependencies } from \"../utils/dependency\";\nimport { updateEnvFile, updateEnvSchema, ENV_CONFIGS } from \"../utils/env-manager\";\nimport chalk from \"chalk\";\nimport { readZuroConfig } from \"../utils/config\";\nimport { showNonZuroProjectMessage } from \"../utils/project-guard\";\n\nfunction resolveSafeTargetPath(projectRoot: string, srcDir: string, file: RegistryFile) {\n const targetPath = path.resolve(projectRoot, srcDir, file.target);\n const normalizedRoot = path.resolve(projectRoot);\n\n if (targetPath !== normalizedRoot && !targetPath.startsWith(`${normalizedRoot}${path.sep}`)) {\n throw new Error(`Refusing to write outside project directory: ${file.target}`);\n }\n\n return targetPath;\n}\n\n/**\n * Modifies app.ts to include error handler middleware\n */\nasync function injectErrorHandler(projectRoot: string, srcDir: string): Promise<boolean> {\n const appPath = path.join(projectRoot, srcDir, \"app.ts\");\n\n if (!fs.existsSync(appPath)) {\n return false;\n }\n\n let content = await fs.readFile(appPath, \"utf-8\");\n\n if (content.includes(\"errorHandler\")) {\n return true;\n }\n\n const errorImport = `import { errorHandler, notFoundHandler } from \"./middleware/error-handler\";`;\n\n const importRegex = /^import .+ from .+;?\\s*$/gm;\n let lastImportIndex = 0;\n let match;\n\n while ((match = importRegex.exec(content)) !== null) {\n lastImportIndex = match.index + match[0].length;\n }\n\n if (lastImportIndex > 0) {\n content = content.slice(0, lastImportIndex) + `\\n${errorImport}` + content.slice(lastImportIndex);\n }\n\n const errorSetup = `\\n// Error handling (must be last)\\napp.use(notFoundHandler);\\napp.use(errorHandler);\\n`;\n const exportMatch = content.match(/export default app;?\\s*$/m);\n if (exportMatch && exportMatch.index !== undefined) {\n content = content.slice(0, exportMatch.index) + errorSetup + \"\\n\" + content.slice(exportMatch.index);\n }\n\n await fs.writeFile(appPath, content);\n return true;\n}\n\n/**\n * Modifies app.ts to include auth routes\n */\nasync function injectAuthRoutes(projectRoot: string, srcDir: string): Promise<boolean> {\n const appPath = path.join(projectRoot, srcDir, \"app.ts\");\n\n if (!fs.existsSync(appPath)) {\n return false;\n }\n\n let content = await fs.readFile(appPath, \"utf-8\");\n\n if (content.includes(\"routes/auth.routes\")) {\n return true;\n }\n\n const authImport = `import authRoutes from \"./routes/auth.routes\";`;\n const userImport = `import userRoutes from \"./routes/user.routes\";`;\n const routeSetup = `\\n// Auth routes\\napp.use(authRoutes);\\napp.use(\"/api/users\", userRoutes);\\n`;\n\n const importRegex = /^import .+ from .+;?\\s*$/gm;\n let lastImportIndex = 0;\n let match;\n\n while ((match = importRegex.exec(content)) !== null) {\n lastImportIndex = match.index + match[0].length;\n }\n\n if (lastImportIndex > 0) {\n content = content.slice(0, lastImportIndex) + `\\n${authImport}\\n${userImport}` + content.slice(lastImportIndex);\n }\n\n const exportMatch = content.match(/export default app;?\\s*$/m);\n if (exportMatch && exportMatch.index !== undefined) {\n content = content.slice(0, exportMatch.index) + routeSetup + \"\\n\" + content.slice(exportMatch.index);\n }\n\n await fs.writeFile(appPath, content);\n return true;\n}\n\nexport const add = async (moduleName: string) => {\n const projectRoot = process.cwd();\n const projectConfig = await readZuroConfig(projectRoot);\n if (!projectConfig) {\n showNonZuroProjectMessage();\n return;\n }\n let srcDir = projectConfig.srcDir || \"src\";\n\n let customDbUrl: string | undefined;\n\n const DEFAULT_URLS = {\n \"database-pg\": \"postgresql://root@localhost:5432/mydb\",\n \"database-mysql\": \"mysql://root@localhost:3306/mydb\",\n };\n\n if (moduleName === \"database\") {\n const variantResponse = await prompts({\n type: \"select\",\n name: \"variant\",\n message: \"Which database dialect?\",\n choices: [\n { title: \"PostgreSQL\", value: \"database-pg\" },\n { title: \"MySQL\", value: \"database-mysql\" },\n ],\n });\n\n if (!variantResponse.variant) {\n process.exit(0);\n }\n\n moduleName = variantResponse.variant;\n\n const defaultUrl = DEFAULT_URLS[moduleName as keyof typeof DEFAULT_URLS];\n console.log(chalk.dim(` Tip: Leave blank to use ${defaultUrl}\\n`));\n\n const urlResponse = await prompts({\n type: \"text\",\n name: \"dbUrl\",\n message: \"Database URL\",\n initial: \"\",\n });\n customDbUrl = urlResponse.dbUrl?.trim() || defaultUrl;\n }\n\n if ((moduleName === \"database-pg\" || moduleName === \"database-mysql\") && customDbUrl === undefined) {\n const defaultUrl = DEFAULT_URLS[moduleName as keyof typeof DEFAULT_URLS];\n console.log(chalk.dim(` Tip: Leave blank to use ${defaultUrl}\\n`));\n\n const response = await prompts({\n type: \"text\",\n name: \"dbUrl\",\n message: \"Database URL\",\n initial: \"\",\n });\n customDbUrl = response.dbUrl?.trim() || defaultUrl;\n }\n\n const spinner = ora(`Checking registry for ${moduleName}...`).start();\n\n try {\n const registryContext = await fetchRegistry();\n const module = registryContext.manifest.modules[moduleName];\n\n if (!module) {\n spinner.fail(`Module '${moduleName}' not found.`);\n return;\n }\n\n spinner.succeed(`Found module: ${chalk.cyan(moduleName)}`);\n\n const moduleDeps = module.moduleDependencies || [];\n await resolveDependencies(moduleDeps, projectRoot);\n\n spinner.start(\"Installing dependencies...\");\n\n let pm = \"npm\";\n if (fs.existsSync(path.join(projectRoot, \"pnpm-lock.yaml\"))) {\n pm = \"pnpm\";\n } else if (fs.existsSync(path.join(projectRoot, \"bun.lockb\"))) {\n pm = \"bun\";\n } else if (fs.existsSync(path.join(projectRoot, \"yarn.lock\"))) {\n pm = \"yarn\";\n }\n\n await installDependencies(pm, module.dependencies || [], projectRoot);\n await installDependencies(pm, module.devDependencies || [], projectRoot, { dev: true });\n\n spinner.succeed(\"Dependencies installed\");\n\n spinner.start(\"Scaffolding files...\");\n\n for (const file of module.files) {\n const content = await fetchFile(file.path, {\n baseUrl: registryContext.fileBaseUrl,\n expectedSha256: file.sha256,\n expectedSize: file.size,\n });\n\n const targetPath = resolveSafeTargetPath(projectRoot, srcDir, file);\n\n await fs.ensureDir(path.dirname(targetPath));\n await fs.writeFile(targetPath, content);\n }\n\n spinner.succeed(\"Files generated\");\n\n if (moduleName === \"auth\") {\n spinner.start(\"Configuring routes in app.ts...\");\n const injected = await injectAuthRoutes(projectRoot, srcDir);\n if (injected) {\n spinner.succeed(\"Routes configured in app.ts\");\n } else {\n spinner.warn(\"Could not find app.ts - routes need manual setup\");\n }\n }\n\n if (moduleName === \"error-handler\") {\n spinner.start(\"Configuring error handler in app.ts...\");\n const injected = await injectErrorHandler(projectRoot, srcDir);\n if (injected) {\n spinner.succeed(\"Error handler configured in app.ts\");\n } else {\n spinner.warn(\"Could not find app.ts - error handler needs manual setup\");\n }\n }\n\n const envConfig = ENV_CONFIGS[moduleName as keyof typeof ENV_CONFIGS];\n if (envConfig) {\n spinner.start(\"Updating environment configuration...\");\n\n const envVars: Record<string, string> = { ...envConfig.envVars };\n if (customDbUrl && (moduleName === \"database-pg\" || moduleName === \"database-mysql\")) {\n envVars.DATABASE_URL = customDbUrl;\n }\n\n await updateEnvFile(projectRoot, envVars);\n await updateEnvSchema(projectRoot, srcDir, envConfig.schemaFields);\n\n spinner.succeed(\"Environment configured\");\n }\n\n console.log(chalk.green(`\\n✔ ${moduleName} added successfully!\\n`));\n\n if (moduleName === \"auth\") {\n console.log(chalk.bold(\"📋 Next Steps:\\n\"));\n console.log(chalk.yellow(\"1. Update your .env file:\"));\n console.log(\n chalk.dim(\" We added placeholder values. Update BETTER_AUTH_SECRET with a secure key.\\n\")\n );\n console.log(chalk.yellow(\"2. Run database migrations:\"));\n console.log(chalk.cyan(\" npx drizzle-kit generate\"));\n console.log(chalk.cyan(\" npx drizzle-kit migrate\\n\"));\n console.log(chalk.yellow(\"3. Available endpoints:\"));\n console.log(chalk.dim(\" POST /auth/sign-up/email - Register\"));\n console.log(chalk.dim(\" POST /auth/sign-in/email - Login\"));\n console.log(chalk.dim(\" POST /auth/sign-out - Logout\"));\n console.log(chalk.dim(\" GET /api/users/me - Current user\\n\"));\n } else if (moduleName === \"error-handler\") {\n console.log(chalk.bold(\"📋 Usage:\\n\"));\n console.log(chalk.yellow(\"Throw errors in your controllers:\"));\n console.log(chalk.dim(\" ─────────────────────────────────────\"));\n console.log(chalk.white(` import { UnauthorizedError, NotFoundError } from \"./lib/errors\";`));\n console.log(\"\");\n console.log(chalk.white(` throw new UnauthorizedError(\"Invalid credentials\");`));\n console.log(chalk.white(` throw new NotFoundError(\"User not found\");`));\n console.log(chalk.dim(\" ─────────────────────────────────────\\n\"));\n console.log(chalk.yellow(\"Available error classes:\"));\n console.log(chalk.dim(\" BadRequestError (400)\"));\n console.log(chalk.dim(\" UnauthorizedError (401)\"));\n console.log(chalk.dim(\" ForbiddenError (403)\"));\n console.log(chalk.dim(\" NotFoundError (404)\"));\n console.log(chalk.dim(\" ConflictError (409)\"));\n console.log(chalk.dim(\" ValidationError (422)\"));\n console.log(chalk.dim(\" InternalServerError (500)\\n\"));\n console.log(chalk.yellow(\"Wrap async handlers:\"));\n console.log(chalk.dim(\" ─────────────────────────────────────\"));\n console.log(chalk.white(` import { asyncHandler } from \"./middleware/error-handler\";`));\n console.log(\"\");\n console.log(chalk.white(` router.get(\"/users\", asyncHandler(async (req, res) => {`));\n console.log(chalk.white(\" // errors auto-caught\"));\n console.log(chalk.white(\" }));\"));\n console.log(chalk.dim(\" ─────────────────────────────────────\\n\"));\n } else if (moduleName.includes(\"database\")) {\n console.log(chalk.bold(\"📋 Next Steps:\\n\"));\n let stepNum = 1;\n\n if (!customDbUrl) {\n console.log(chalk.yellow(`${stepNum}. Update DATABASE_URL in .env:`));\n console.log(\n chalk.dim(\" We added a placeholder. Update with your actual database credentials.\\n\")\n );\n stepNum++;\n }\n\n console.log(chalk.yellow(`${stepNum}. Create schemas in src/db/schema/:`));\n console.log(chalk.dim(\" Add table files and export from index.ts\\n\"));\n stepNum++;\n\n console.log(chalk.yellow(`${stepNum}. Run migrations:`));\n console.log(chalk.cyan(\" npx drizzle-kit generate\"));\n console.log(chalk.cyan(\" npx drizzle-kit migrate\\n\"));\n }\n } catch (error) {\n spinner.fail(`Failed to add module: ${(error as Error).message}`);\n }\n};\n","import { add } from \"../commands/add\";\nimport { readZuroConfig } from \"./config\";\nimport fs from \"fs-extra\";\nimport path from \"path\";\nimport chalk from \"chalk\";\n\n// Signature files to check if a Zuro module is installed\nconst BLOCK_SIGNATURES: Record<string, string> = {\n core: \"env.ts\",\n \"database-pg\": \"db/index.ts\",\n \"database-mysql\": \"db/index.ts\",\n validator: \"middleware/validate.ts\",\n \"error-handler\": \"lib/errors.ts\",\n logger: \"lib/logger.ts\",\n auth: \"lib/auth.ts\",\n};\n\n/**\n * Resolves Zuro module dependencies (NOT npm packages).\n * Only handles module dependencies like \"core\", \"database\", \"validator\", \"auth\".\n */\nexport const resolveDependencies = async (\n moduleDependencies: string[] | undefined,\n cwd: string\n) => {\n if (!moduleDependencies || moduleDependencies.length === 0) {\n return;\n }\n\n const config = await readZuroConfig(cwd);\n const srcDir = config?.srcDir || \"src\";\n\n for (const dep of moduleDependencies) {\n if (dep === \"database\") {\n const pgExists = fs.existsSync(path.join(cwd, srcDir, BLOCK_SIGNATURES[\"database-pg\"]));\n const mysqlExists = fs.existsSync(path.join(cwd, srcDir, BLOCK_SIGNATURES[\"database-mysql\"]));\n\n if (pgExists || mysqlExists) {\n continue;\n }\n\n console.log(chalk.blue(`ℹ Dependency '${dep}' is missing. Triggering install...`));\n await add(\"database\");\n continue;\n }\n\n const signature = BLOCK_SIGNATURES[dep];\n if (!signature) {\n continue;\n }\n\n if (fs.existsSync(path.join(cwd, srcDir, signature))) {\n continue;\n }\n\n console.log(chalk.blue(`ℹ Installing missing dependency: ${dep}...`));\n await add(dep);\n }\n};\n"],"mappings":"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","names":["chalk","fs","path","fs","path","fs","path","path","fs","chalk","prompts","ora","path","fs","fs","path","chalk","chalk","resolveSafeTargetPath","path","fs","prompts","chalk","ora"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zuro-cli",
3
- "version": "0.0.2-beta.0",
3
+ "version": "0.0.2-beta.2",
4
4
  "description": "The backend builder for busy developers.",
5
5
  "bin": {
6
6
  "zuro-cli": "./dist/index.js"