zuro-cli 0.0.2-beta.7 → 0.0.2-beta.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -904,69 +904,117 @@ ${setupLines.join("\n")}
904
904
  }
905
905
  async function injectAuthRoutes(projectRoot, srcDir) {
906
906
  const appPath = import_path6.default.join(projectRoot, srcDir, "app.ts");
907
- if (!import_fs_extra6.default.existsSync(appPath)) {
907
+ if (!await import_fs_extra6.default.pathExists(appPath)) {
908
908
  return false;
909
909
  }
910
- let content = await import_fs_extra6.default.readFile(appPath, "utf-8");
911
- const authImport = `import authRoutes from "./routes/auth.routes";`;
910
+ let appContent = await import_fs_extra6.default.readFile(appPath, "utf-8");
911
+ const authHandlerImport = `import { toNodeHandler } from "better-auth/node";`;
912
+ const authImport = `import { auth } from "./lib/auth";`;
912
913
  const userImport = `import userRoutes from "./routes/user.routes";`;
913
- const hasAuthImport = content.includes(authImport);
914
- const hasUserImport = content.includes(userImport);
915
- const hasAuthRoute = /app\.use\(\s*authRoutes\s*\)/.test(content);
916
- const hasUserRoute = /app\.use\(\s*["']\/api\/users["']\s*,\s*userRoutes\s*\)/.test(content);
917
- let modified = false;
918
- let importsReady = hasAuthImport && hasUserImport;
919
- if (!importsReady) {
914
+ let appModified = false;
915
+ const appendImport = (source, line) => {
916
+ if (source.includes(line)) {
917
+ return { source, inserted: true };
918
+ }
920
919
  const importRegex = /^import .+ from .+;?\s*$/gm;
921
920
  let lastImportIndex = 0;
922
921
  let match;
923
- while ((match = importRegex.exec(content)) !== null) {
922
+ while ((match = importRegex.exec(source)) !== null) {
924
923
  lastImportIndex = match.index + match[0].length;
925
924
  }
926
- if (lastImportIndex > 0) {
927
- const missingImports = [];
928
- if (!hasAuthImport) {
929
- missingImports.push(authImport);
930
- }
931
- if (!hasUserImport) {
932
- missingImports.push(userImport);
933
- }
934
- content = content.slice(0, lastImportIndex) + `
935
- ${missingImports.join("\n")}` + content.slice(lastImportIndex);
936
- modified = true;
937
- importsReady = true;
925
+ if (lastImportIndex <= 0) {
926
+ return { source, inserted: false };
927
+ }
928
+ return {
929
+ source: source.slice(0, lastImportIndex) + `
930
+ ${line}` + source.slice(lastImportIndex),
931
+ inserted: true
932
+ };
933
+ };
934
+ for (const importLine of [authHandlerImport, authImport]) {
935
+ const next = appendImport(appContent, importLine);
936
+ if (!next.inserted) {
937
+ return false;
938
+ }
939
+ if (next.source !== appContent) {
940
+ appContent = next.source;
941
+ appModified = true;
938
942
  }
939
943
  }
940
- let setupReady = hasAuthRoute && hasUserRoute;
941
- if (!setupReady) {
942
- const setupLines = [];
943
- if (!hasAuthRoute) {
944
- setupLines.push("app.use(authRoutes);");
944
+ const hasAuthMount = /toNodeHandler\(\s*auth\s*\)/.test(appContent) && /\/api\/auth/.test(appContent);
945
+ if (!hasAuthMount) {
946
+ const authMountLine = "app.all(/^\\/api\\/auth(?:\\/.*)?$/, toNodeHandler(auth));\n";
947
+ const jsonIndex = appContent.search(/^\s*app\.use\(\s*express\.json\(\)\s*\);\s*$/m);
948
+ let insertionIndex = jsonIndex;
949
+ if (insertionIndex < 0) {
950
+ const healthIndex = appContent.search(/^\s*app\.get\(\s*["']\/health["']\s*,/m);
951
+ insertionIndex = healthIndex;
945
952
  }
953
+ if (insertionIndex < 0) {
954
+ const exportMatch = appContent.match(/export default app;?\s*$/m);
955
+ insertionIndex = exportMatch?.index ?? -1;
956
+ }
957
+ if (insertionIndex < 0) {
958
+ return false;
959
+ }
960
+ appContent = appContent.slice(0, insertionIndex) + authMountLine + appContent.slice(insertionIndex);
961
+ appModified = true;
962
+ }
963
+ const routeIndexPath = import_path6.default.join(projectRoot, srcDir, "routes", "index.ts");
964
+ if (await import_fs_extra6.default.pathExists(routeIndexPath)) {
965
+ let routeContent = await import_fs_extra6.default.readFile(routeIndexPath, "utf-8");
966
+ let routeModified = false;
967
+ const userImportResult = appendImport(routeContent, userImport);
968
+ if (!userImportResult.inserted) {
969
+ return false;
970
+ }
971
+ if (userImportResult.source !== routeContent) {
972
+ routeContent = userImportResult.source;
973
+ routeModified = true;
974
+ }
975
+ const hasUserRoute = /rootRouter\.use\(\s*["']\/users["']\s*,\s*userRoutes\s*\)/.test(routeContent);
946
976
  if (!hasUserRoute) {
947
- setupLines.push('app.use("/api/users", userRoutes);');
977
+ const routeSetup = `
978
+ // User routes
979
+ rootRouter.use("/users", userRoutes);
980
+ `;
981
+ const exportMatch = routeContent.match(/export default rootRouter;?\s*$/m);
982
+ if (!exportMatch || exportMatch.index === void 0) {
983
+ return false;
984
+ }
985
+ routeContent = routeContent.slice(0, exportMatch.index) + routeSetup + "\n" + routeContent.slice(exportMatch.index);
986
+ routeModified = true;
948
987
  }
949
- const routeSetup = `
950
- // Auth routes
951
- ${setupLines.join("\n")}
988
+ if (routeModified) {
989
+ await import_fs_extra6.default.writeFile(routeIndexPath, routeContent);
990
+ }
991
+ } else {
992
+ const hasUserRoute = /app\.use\(\s*["']\/api\/users["']\s*,\s*userRoutes\s*\)/.test(appContent);
993
+ if (!hasUserRoute) {
994
+ const exportMatch = appContent.match(/export default app;?\s*$/m);
995
+ if (!exportMatch || exportMatch.index === void 0) {
996
+ return false;
997
+ }
998
+ const routeSetup = `
999
+ // User routes
1000
+ app.use("/api/users", userRoutes);
952
1001
  `;
953
- const notFoundIndex = content.search(/^\s*app\.use\(\s*notFoundHandler\s*\);\s*$/m);
954
- const errorHandlerIndex = content.search(/^\s*app\.use\(\s*errorHandler\s*\);\s*$/m);
955
- const candidates = [notFoundIndex, errorHandlerIndex].filter((index) => index >= 0);
956
- const insertionIndex = candidates.length > 0 ? Math.min(...candidates) : (() => {
957
- const exportMatch = content.match(/export default app;?\s*$/m);
958
- return exportMatch?.index ?? -1;
959
- })();
960
- if (insertionIndex >= 0) {
961
- content = content.slice(0, insertionIndex) + routeSetup + "\n" + content.slice(insertionIndex);
962
- modified = true;
963
- setupReady = true;
1002
+ appContent = appContent.slice(0, exportMatch.index) + routeSetup + "\n" + appContent.slice(exportMatch.index);
1003
+ appModified = true;
1004
+ }
1005
+ const userImportResult = appendImport(appContent, userImport);
1006
+ if (!userImportResult.inserted) {
1007
+ return false;
1008
+ }
1009
+ if (userImportResult.source !== appContent) {
1010
+ appContent = userImportResult.source;
1011
+ appModified = true;
964
1012
  }
965
1013
  }
966
- if (modified) {
967
- await import_fs_extra6.default.writeFile(appPath, content);
1014
+ if (appModified) {
1015
+ await import_fs_extra6.default.writeFile(appPath, appContent);
968
1016
  }
969
- return importsReady && setupReady;
1017
+ return true;
970
1018
  }
971
1019
  var add = async (moduleName) => {
972
1020
  const projectRoot = process.cwd();
@@ -1109,12 +1157,12 @@ var add = async (moduleName) => {
1109
1157
  }
1110
1158
  spinner.succeed("Files generated");
1111
1159
  if (resolvedModuleName === "auth") {
1112
- spinner.start("Configuring routes in app.ts...");
1160
+ spinner.start("Configuring routes...");
1113
1161
  const injected = await injectAuthRoutes(projectRoot, srcDir);
1114
1162
  if (injected) {
1115
- spinner.succeed("Routes configured in app.ts");
1163
+ spinner.succeed("Routes configured");
1116
1164
  } else {
1117
- spinner.warn("Could not find app.ts - routes need manual setup");
1165
+ spinner.warn("Could not configure routes automatically");
1118
1166
  }
1119
1167
  }
1120
1168
  if (resolvedModuleName === "error-handler") {
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, 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\nasync function setupPrettier(targetDir: string) {\n const prettierConfigPath = path.join(targetDir, \".prettierrc\");\n const prettierIgnorePath = path.join(targetDir, \".prettierignore\");\n\n if (!await fs.pathExists(prettierConfigPath)) {\n const prettierConfig = {\n semi: true,\n singleQuote: false,\n trailingComma: \"es5\",\n printWidth: 100,\n tabWidth: 2,\n };\n await fs.writeJson(prettierConfigPath, prettierConfig, { spaces: 2 });\n }\n\n if (!await fs.pathExists(prettierIgnorePath)) {\n const ignoreContent = `node_modules\ndist\nbuild\ncoverage\n.next\npnpm-lock.yaml\npackage-lock.json\nbun.lock\nbun.lockb\n`;\n await fs.writeFile(prettierIgnorePath, ignoreContent);\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 let enablePrettier = false;\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 type: \"confirm\",\n name: \"prettier\",\n message: \"Setup Prettier?\",\n initial: true,\n },\n ]);\n\n if (response.pm === undefined) {\n console.log(chalk.red(\"Operation cancelled.\"));\n return;\n }\n\n pm = response.pm;\n enablePrettier = response.prettier === true;\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, { enablePrettier });\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 if (enablePrettier) {\n await installDependencies(pm, [\"prettier\"], targetDir, { dev: true });\n }\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 if (enablePrettier) {\n currentStep = \"prettier setup\";\n await setupPrettier(targetDir);\n }\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 options: { enablePrettier?: boolean } = {}\n) {\n const pkgPath = path.join(cwd, \"package.json\");\n if (force || !await fs.pathExists(pkgPath)) {\n const scripts: Record<string, string> = {\n \"dev\": `tsx watch ${srcDir}/server.ts`,\n \"build\": \"tsc\",\n \"start\": \"node dist/server.js\"\n };\n\n if (options.enablePrettier) {\n scripts[\"format\"] = \"prettier --write .\";\n scripts[\"format:check\"] = \"prettier --check .\";\n }\n\n await fs.writeJson(pkgPath, {\n name: normalizePackageName(packageName),\n version: \"0.0.1\",\n private: true,\n scripts\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 (\n cwd: string,\n variables: Record<string, string>,\n createIfMissing = true,\n options: { overwriteExisting?: boolean } = {}\n) => {\n const envPath = path.join(cwd, \".env\");\n const overwriteExisting = options.overwriteExisting ?? false;\n\n let content = \"\";\n if (fs.existsSync(envPath)) {\n content = await fs.readFile(envPath, \"utf-8\");\n } else if (!createIfMissing) {\r\n return;\r\n }\r\n\r\n let modified = false;\n\n for (const [key, value] of Object.entries(variables)) {\n const escapedKey = key.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const regex = new RegExp(`^${escapedKey}=.*$`, \"m\");\n\n if (regex.test(content)) {\n if (!overwriteExisting) {\n continue;\n }\n\n const nextLine = `${key}=${value}`;\n const updated = content.replace(regex, nextLine);\n if (updated !== content) {\n content = updated;\n modified = true;\n }\n continue;\n }\n\n // Add newline if content doesn't end with one\n if (content && !content.endsWith(\"\\n\")) {\n content += os.EOL;\n }\n content += `${key}=${value}${os.EOL}`;\n modified = true;\n }\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\nexport function showInitFirstMessage() {\n console.log(chalk.yellow(\"No Zuro project found in this directory.\"));\n console.log(\"\");\n console.log(chalk.yellow(\"Run init first, then add modules.\"));\n console.log(\"\");\n console.log(chalk.cyan(\"npx zuro-cli init\"));\n}\n","import prompts from \"prompts\";\nimport ora from \"ora\";\nimport path from \"path\";\nimport fs from \"fs-extra\";\nimport { randomBytes } from \"node:crypto\";\nimport { fetchRegistry, fetchFile, RegistryFile } from \"../utils/registry\";\nimport { installDependencies, ensurePackageManagerAvailable } 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, showInitFirstMessage } from \"../utils/project-guard\";\n\ntype DatabaseModuleName = \"database-pg\" | \"database-mysql\";\n\nexport interface AddCommandOptions {\n dialect?: string;\n dbUrl?: string;\n yes?: boolean;\n}\n\nconst DEFAULT_DATABASE_URLS: Record<DatabaseModuleName, string> = {\n \"database-pg\": \"postgresql://postgres@localhost:5432/mydb\",\n \"database-mysql\": \"mysql://root@localhost:3306/mydb\",\n};\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\nfunction resolvePackageManager(projectRoot: string) {\n if (fs.existsSync(path.join(projectRoot, \"pnpm-lock.yaml\"))) {\n return \"pnpm\";\n }\n\n if (fs.existsSync(path.join(projectRoot, \"bun.lockb\")) || fs.existsSync(path.join(projectRoot, \"bun.lock\"))) {\n return \"bun\";\n }\n\n if (fs.existsSync(path.join(projectRoot, \"yarn.lock\"))) {\n return \"yarn\";\n }\n\n return \"npm\";\n}\n\nfunction parseDatabaseDialect(value?: string): DatabaseModuleName | null {\n const normalized = value?.trim().toLowerCase();\n if (!normalized) {\n return null;\n }\n\n if (normalized === \"pg\" || normalized === \"postgres\" || normalized === \"postgresql\" || normalized === \"database-pg\") {\n return \"database-pg\";\n }\n\n if (normalized === \"mysql\" || normalized === \"database-mysql\") {\n return \"database-mysql\";\n }\n\n return null;\n}\n\nfunction isDatabaseModule(moduleName: string): moduleName is DatabaseModuleName {\n return moduleName === \"database-pg\" || moduleName === \"database-mysql\";\n}\n\nfunction validateDatabaseUrl(rawUrl: string, moduleName: DatabaseModuleName) {\n const dbUrl = rawUrl.trim();\n if (!dbUrl) {\n throw new Error(\"Database URL cannot be empty.\");\n }\n\n let parsed: URL;\n try {\n parsed = new URL(dbUrl);\n } catch {\n throw new Error(`Invalid database URL: '${dbUrl}'.`);\n }\n\n const protocol = parsed.protocol.toLowerCase();\n if (moduleName === \"database-pg\" && protocol !== \"postgresql:\" && protocol !== \"postgres:\") {\n throw new Error(\"PostgreSQL URL must start with postgres:// or postgresql://\");\n }\n\n if (moduleName === \"database-mysql\" && protocol !== \"mysql:\") {\n throw new Error(\"MySQL URL must start with mysql://\");\n }\n\n return dbUrl;\n}\n\nasync function detectInstalledDatabaseDialect(projectRoot: string, srcDir: string): Promise<DatabaseModuleName | null> {\n const dbIndexPath = path.join(projectRoot, srcDir, \"db\", \"index.ts\");\n if (!fs.existsSync(dbIndexPath)) {\n return null;\n }\n\n const content = await fs.readFile(dbIndexPath, \"utf-8\");\n if (content.includes(\"drizzle-orm/node-postgres\") || content.includes(`from \"pg\"`)) {\n return \"database-pg\";\n }\n\n if (content.includes(\"drizzle-orm/mysql2\") || content.includes(`from \"mysql2`)) {\n return \"database-mysql\";\n }\n\n return null;\n}\n\nasync function backupDatabaseFiles(projectRoot: string, srcDir: string): Promise<string | null> {\n const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const backupRoot = path.join(projectRoot, \".zuro\", \"backups\", `database-${timestamp}`);\n const candidates = [\n path.join(projectRoot, srcDir, \"db\", \"index.ts\"),\n path.join(projectRoot, \"drizzle.config.ts\"),\n ];\n\n let copied = false;\n for (const filePath of candidates) {\n if (!fs.existsSync(filePath)) {\n continue;\n }\n\n const relativePath = path.relative(projectRoot, filePath);\n const backupPath = path.join(backupRoot, relativePath);\n await fs.ensureDir(path.dirname(backupPath));\n await fs.copyFile(filePath, backupPath);\n copied = true;\n }\n\n return copied ? backupRoot : null;\n}\n\nfunction databaseLabel(moduleName: DatabaseModuleName) {\n return moduleName === \"database-pg\" ? \"PostgreSQL\" : \"MySQL\";\n}\n\nfunction getDatabaseSetupHint(moduleName: DatabaseModuleName, dbUrl: string) {\n try {\n const parsed = new URL(dbUrl);\n const dbName = parsed.pathname.replace(/^\\/+/, \"\") || \"mydb\";\n\n if (moduleName === \"database-pg\") {\n return `createdb ${dbName}`;\n }\n\n return `mysql -e \"CREATE DATABASE IF NOT EXISTS ${dbName};\"`;\n } catch {\n return moduleName === \"database-pg\"\n ? \"createdb <database_name>\"\n : `mysql -e \"CREATE DATABASE IF NOT EXISTS <database_name>;\"`;\n }\n}\n\nfunction getModuleDocsPath(moduleName: string) {\n if (isDatabaseModule(moduleName)) {\n return \"database\";\n }\n\n return moduleName;\n}\n\nfunction escapeRegex(value: string) {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nasync function hasEnvVariable(projectRoot: string, key: string): Promise<boolean> {\n const envPath = path.join(projectRoot, \".env\");\n if (!await fs.pathExists(envPath)) {\n return false;\n }\n\n const content = await fs.readFile(envPath, \"utf-8\");\n const pattern = new RegExp(`^${escapeRegex(key)}=`, \"m\");\n return pattern.test(content);\n}\n\nasync function isLikelyEmptyDirectory(cwd: string): Promise<boolean> {\n const entries = await fs.readdir(cwd);\n const ignored = new Set([\".ds_store\", \"thumbs.db\"]);\n\n return entries.filter((entry) => !ignored.has(entry.toLowerCase())).length === 0;\n}\n\nasync function ensureSchemaExport(projectRoot: string, srcDir: string, schemaFileName: string) {\n const schemaIndexPath = path.join(projectRoot, srcDir, \"db\", \"schema\", \"index.ts\");\n if (!await fs.pathExists(schemaIndexPath)) {\n return;\n }\n\n const exportLine = `export * from \"./${schemaFileName}\";`;\n const content = await fs.readFile(schemaIndexPath, \"utf-8\");\n const normalized = content.replace(/\\r\\n/g, \"\\n\");\n const exportPattern = new RegExp(\n `^\\\\s*export\\\\s*\\\\*\\\\s*from\\\\s*[\"']\\\\./${escapeRegex(schemaFileName)}[\"'];?\\\\s*$`,\n \"m\"\n );\n\n if (exportPattern.test(normalized)) {\n return;\n }\n\n let next = normalized\n .replace(/^\\s*export\\s*\\{\\s*\\};?\\s*$/m, \"\")\n .trimEnd();\n\n if (next.length > 0) {\n next += \"\\n\\n\";\n }\n\n next += `${exportLine}\\n`;\n await fs.writeFile(schemaIndexPath, next);\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 const errorImport = `import { errorHandler, notFoundHandler } from \"./middleware/error-handler\";`;\n const hasErrorImport = content.includes(errorImport);\n const hasNotFoundUse = /app\\.use\\(\\s*notFoundHandler\\s*\\)/.test(content);\n const hasErrorUse = /app\\.use\\(\\s*errorHandler\\s*\\)/.test(content);\n let modified = false;\n let importInserted = hasErrorImport;\n\n if (!hasErrorImport) {\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 modified = true;\n importInserted = true;\n }\n }\n\n let setupInserted = hasNotFoundUse && hasErrorUse;\n if (!setupInserted) {\n const setupLines: string[] = [];\n if (!hasNotFoundUse) {\n setupLines.push(\"app.use(notFoundHandler);\");\n }\n\n if (!hasErrorUse) {\n setupLines.push(\"app.use(errorHandler);\");\n }\n\n const errorSetup = `\\n// Error handling (must be last)\\n${setupLines.join(\"\\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) + errorSetup + \"\\n\" + content.slice(exportMatch.index);\n modified = true;\n setupInserted = true;\n }\n }\n\n if (modified) {\n await fs.writeFile(appPath, content);\n }\n\n return importInserted && setupInserted;\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 const authImport = `import authRoutes from \"./routes/auth.routes\";`;\n const userImport = `import userRoutes from \"./routes/user.routes\";`;\n const hasAuthImport = content.includes(authImport);\n const hasUserImport = content.includes(userImport);\n const hasAuthRoute = /app\\.use\\(\\s*authRoutes\\s*\\)/.test(content);\n const hasUserRoute = /app\\.use\\(\\s*[\"']\\/api\\/users[\"']\\s*,\\s*userRoutes\\s*\\)/.test(content);\n let modified = false;\n let importsReady = hasAuthImport && hasUserImport;\n\n if (!importsReady) {\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 const missingImports: string[] = [];\n if (!hasAuthImport) {\n missingImports.push(authImport);\n }\n\n if (!hasUserImport) {\n missingImports.push(userImport);\n }\n\n content = content.slice(0, lastImportIndex) + `\\n${missingImports.join(\"\\n\")}` + content.slice(lastImportIndex);\n modified = true;\n importsReady = true;\n }\n }\n\n let setupReady = hasAuthRoute && hasUserRoute;\n if (!setupReady) {\n const setupLines: string[] = [];\n if (!hasAuthRoute) {\n setupLines.push(\"app.use(authRoutes);\");\n }\n\n if (!hasUserRoute) {\n setupLines.push('app.use(\"/api/users\", userRoutes);');\n }\n\n const routeSetup = `\\n// Auth routes\\n${setupLines.join(\"\\n\")}\\n`;\n const notFoundIndex = content.search(/^\\s*app\\.use\\(\\s*notFoundHandler\\s*\\);\\s*$/m);\n const errorHandlerIndex = content.search(/^\\s*app\\.use\\(\\s*errorHandler\\s*\\);\\s*$/m);\n const candidates = [notFoundIndex, errorHandlerIndex].filter((index) => index >= 0);\n const insertionIndex = candidates.length > 0\n ? Math.min(...candidates)\n : (() => {\n const exportMatch = content.match(/export default app;?\\s*$/m);\n return exportMatch?.index ?? -1;\n })();\n\n if (insertionIndex >= 0) {\n content = content.slice(0, insertionIndex) + routeSetup + \"\\n\" + content.slice(insertionIndex);\n modified = true;\n setupReady = true;\n }\n }\n\n if (modified) {\n await fs.writeFile(appPath, content);\n }\n\n return importsReady && setupReady;\n}\n\nexport const add = async (moduleName: string) => {\n const projectRoot = process.cwd();\n const projectConfig = await readZuroConfig(projectRoot);\n if (!projectConfig) {\n if (await isLikelyEmptyDirectory(projectRoot)) {\n showInitFirstMessage();\n return;\n }\n\n showNonZuroProjectMessage();\n return;\n }\n const srcDir = projectConfig.srcDir || \"src\";\n let resolvedModuleName = moduleName;\n const parsedDialect = parseDatabaseDialect(moduleName);\n if (parsedDialect) {\n resolvedModuleName = parsedDialect;\n }\n\n let customDbUrl: string | undefined;\n let usedDefaultDbUrl = false;\n let databaseBackupPath: string | null = null;\n let generatedAuthSecret = false;\n let authDatabaseDialect: DatabaseModuleName | null = null;\n\n if (resolvedModuleName === \"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 console.log(chalk.yellow(\"Operation cancelled.\"));\n return;\n }\n\n resolvedModuleName = variantResponse.variant;\n }\n\n if (isDatabaseModule(resolvedModuleName)) {\n const installedDialect = await detectInstalledDatabaseDialect(projectRoot, srcDir);\n\n if (installedDialect && installedDialect !== resolvedModuleName) {\n console.log(\n chalk.yellow(\n `\\n⚠ Existing database setup detected: ${databaseLabel(installedDialect)}.`\n )\n );\n console.log(\n chalk.yellow(\n ` Switching to ${databaseLabel(resolvedModuleName)} will overwrite db files and drizzle config.\\n`\n )\n );\n\n const switchResponse = await prompts({\n type: \"confirm\",\n name: \"proceed\",\n message: \"Continue and switch database dialect?\",\n initial: false,\n });\n\n if (!switchResponse.proceed) {\n console.log(chalk.yellow(\"Operation cancelled.\"));\n return;\n }\n\n databaseBackupPath = await backupDatabaseFiles(projectRoot, srcDir);\n }\n\n const defaultUrl = DEFAULT_DATABASE_URLS[resolvedModuleName];\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\n if (response.dbUrl === undefined) {\n console.log(chalk.yellow(\"Operation cancelled.\"));\n return;\n }\n\n const enteredUrl = response.dbUrl?.trim() || \"\";\n usedDefaultDbUrl = enteredUrl.length === 0;\n customDbUrl = validateDatabaseUrl(enteredUrl || defaultUrl, resolvedModuleName);\n }\n\n const pm = resolvePackageManager(projectRoot);\n const spinner = ora(`Checking registry for ${resolvedModuleName}...`).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 = `Checking registry for ${resolvedModuleName}...`;\n const registryContext = await fetchRegistry();\n const module = registryContext.manifest.modules[resolvedModuleName];\n\n if (!module) {\n spinner.fail(`Module '${resolvedModuleName}' not found.`);\n return;\n }\n\n spinner.succeed(`Found module: ${chalk.cyan(resolvedModuleName)}`);\n\n const moduleDeps = module.moduleDependencies || [];\n currentStep = \"module dependency resolution\";\n await resolveDependencies(moduleDeps, projectRoot);\n\n currentStep = \"dependency installation\";\n spinner.start(\"Installing dependencies...\");\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 currentStep = \"module scaffolding\";\n spinner.start(\"Scaffolding files...\");\n\n if (resolvedModuleName === \"auth\") {\n authDatabaseDialect = await detectInstalledDatabaseDialect(projectRoot, srcDir);\n }\n\n for (const file of module.files) {\n let fetchPath = file.path;\n let expectedSha256 = file.sha256;\n let expectedSize = file.size;\n\n if (\n resolvedModuleName === \"auth\"\n && file.target === \"db/schema/auth.ts\"\n && authDatabaseDialect === \"database-mysql\"\n ) {\n fetchPath = \"express/db/schema/auth.mysql.ts\";\n expectedSha256 = undefined;\n expectedSize = undefined;\n }\n\n let content = await fetchFile(fetchPath, {\n baseUrl: registryContext.fileBaseUrl,\n expectedSha256,\n expectedSize,\n });\n\n if (isDatabaseModule(resolvedModuleName) && file.target === \"../drizzle.config.ts\") {\n const normalizedSrcDir = srcDir.replace(/\\\\/g, \"/\");\n content = content.replace(\n /schema:\\s*[\"'][^\"']+[\"']/,\n `schema: \"./${normalizedSrcDir}/db/schema/*\"`\n );\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 const schemaExports = module.files\n .map((file) => file.target.replace(/\\\\/g, \"/\"))\n .filter((target) => /^db\\/schema\\/[^/]+\\.ts$/.test(target))\n .map((target) => path.posix.basename(target, \".ts\"))\n .filter((name) => name !== \"index\");\n\n for (const schemaFileName of schemaExports) {\n await ensureSchemaExport(projectRoot, srcDir, schemaFileName);\n }\n\n spinner.succeed(\"Files generated\");\n\n if (resolvedModuleName === \"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 (resolvedModuleName === \"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[resolvedModuleName as keyof typeof ENV_CONFIGS];\n if (envConfig) {\n currentStep = \"environment configuration\";\n spinner.start(\"Updating environment configuration...\");\n\n const envVars: Record<string, string> = { ...envConfig.envVars };\n if (customDbUrl && isDatabaseModule(resolvedModuleName)) {\n envVars.DATABASE_URL = customDbUrl;\n }\n\n if (resolvedModuleName === \"auth\") {\n const hasExistingSecret = await hasEnvVariable(projectRoot, \"BETTER_AUTH_SECRET\");\n if (!hasExistingSecret) {\n envVars.BETTER_AUTH_SECRET = randomBytes(32).toString(\"hex\");\n generatedAuthSecret = true;\n }\n }\n\n await updateEnvFile(projectRoot, envVars, true, {\n overwriteExisting: isDatabaseModule(resolvedModuleName),\n });\n await updateEnvSchema(projectRoot, srcDir, envConfig.schemaFields);\n\n spinner.succeed(\"Environment configured\");\n }\n\n console.log(chalk.green(`\\n✔ ${resolvedModuleName} added successfully!\\n`));\n\n if (databaseBackupPath) {\n console.log(chalk.blue(`ℹ Backup created at: ${databaseBackupPath}\\n`));\n }\n\n const docsPath = getModuleDocsPath(resolvedModuleName);\n const docsUrl = `https://zuro-cli.devbybriyan.com/docs/${docsPath}`;\n console.log(chalk.blue(`ℹ Docs: ${docsUrl}`));\n\n if (isDatabaseModule(resolvedModuleName)) {\n if (usedDefaultDbUrl) {\n console.log(chalk.yellow(\"ℹ Review DATABASE_URL in .env if your local DB config differs.\"));\n }\n\n const setupHint = getDatabaseSetupHint(\n resolvedModuleName,\n customDbUrl || DEFAULT_DATABASE_URLS[resolvedModuleName]\n );\n console.log(chalk.yellow(`ℹ Ensure DB exists: ${setupHint}`));\n console.log(chalk.yellow(\"ℹ Run migrations: npx drizzle-kit generate && npx drizzle-kit migrate\"));\n }\n\n if (resolvedModuleName === \"auth\") {\n if (generatedAuthSecret) {\n console.log(chalk.yellow(\"ℹ BETTER_AUTH_SECRET was generated automatically.\"));\n } else {\n console.log(chalk.yellow(\"ℹ Review BETTER_AUTH_SECRET and BETTER_AUTH_URL in .env.\"));\n }\n\n console.log(chalk.yellow(\"ℹ Run migrations: npx drizzle-kit generate && npx drizzle-kit migrate\"));\n }\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 console.log(chalk.cyan(` npx zuro-cli add ${resolvedModuleName}`));\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_node_crypto","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\nasync function setupPrettier(targetDir: string) {\n const prettierConfigPath = path.join(targetDir, \".prettierrc\");\n const prettierIgnorePath = path.join(targetDir, \".prettierignore\");\n\n if (!await fs.pathExists(prettierConfigPath)) {\n const prettierConfig = {\n semi: true,\n singleQuote: false,\n trailingComma: \"es5\",\n printWidth: 100,\n tabWidth: 2,\n };\n await fs.writeJson(prettierConfigPath, prettierConfig, { spaces: 2 });\n }\n\n if (!await fs.pathExists(prettierIgnorePath)) {\n const ignoreContent = `node_modules\ndist\nbuild\ncoverage\n.next\npnpm-lock.yaml\npackage-lock.json\nbun.lock\nbun.lockb\n`;\n await fs.writeFile(prettierIgnorePath, ignoreContent);\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 let enablePrettier = false;\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 type: \"confirm\",\n name: \"prettier\",\n message: \"Setup Prettier?\",\n initial: true,\n },\n ]);\n\n if (response.pm === undefined) {\n console.log(chalk.red(\"Operation cancelled.\"));\n return;\n }\n\n pm = response.pm;\n enablePrettier = response.prettier === true;\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, { enablePrettier });\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 if (enablePrettier) {\n await installDependencies(pm, [\"prettier\"], targetDir, { dev: true });\n }\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 if (enablePrettier) {\n currentStep = \"prettier setup\";\n await setupPrettier(targetDir);\n }\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 options: { enablePrettier?: boolean } = {}\n) {\n const pkgPath = path.join(cwd, \"package.json\");\n if (force || !await fs.pathExists(pkgPath)) {\n const scripts: Record<string, string> = {\n \"dev\": `tsx watch ${srcDir}/server.ts`,\n \"build\": \"tsc\",\n \"start\": \"node dist/server.js\"\n };\n\n if (options.enablePrettier) {\n scripts[\"format\"] = \"prettier --write .\";\n scripts[\"format:check\"] = \"prettier --check .\";\n }\n\n await fs.writeJson(pkgPath, {\n name: normalizePackageName(packageName),\n version: \"0.0.1\",\n private: true,\n scripts\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 (\n cwd: string,\n variables: Record<string, string>,\n createIfMissing = true,\n options: { overwriteExisting?: boolean } = {}\n) => {\n const envPath = path.join(cwd, \".env\");\n const overwriteExisting = options.overwriteExisting ?? false;\n\n let content = \"\";\n if (fs.existsSync(envPath)) {\n content = await fs.readFile(envPath, \"utf-8\");\n } else if (!createIfMissing) {\r\n return;\r\n }\r\n\r\n let modified = false;\n\n for (const [key, value] of Object.entries(variables)) {\n const escapedKey = key.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const regex = new RegExp(`^${escapedKey}=.*$`, \"m\");\n\n if (regex.test(content)) {\n if (!overwriteExisting) {\n continue;\n }\n\n const nextLine = `${key}=${value}`;\n const updated = content.replace(regex, nextLine);\n if (updated !== content) {\n content = updated;\n modified = true;\n }\n continue;\n }\n\n // Add newline if content doesn't end with one\n if (content && !content.endsWith(\"\\n\")) {\n content += os.EOL;\n }\n content += `${key}=${value}${os.EOL}`;\n modified = true;\n }\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\nexport function showInitFirstMessage() {\n console.log(chalk.yellow(\"No Zuro project found in this directory.\"));\n console.log(\"\");\n console.log(chalk.yellow(\"Run init first, then add modules.\"));\n console.log(\"\");\n console.log(chalk.cyan(\"npx zuro-cli init\"));\n}\n","import prompts from \"prompts\";\nimport ora from \"ora\";\nimport path from \"path\";\nimport fs from \"fs-extra\";\nimport { randomBytes } from \"node:crypto\";\nimport { fetchRegistry, fetchFile, RegistryFile } from \"../utils/registry\";\nimport { installDependencies, ensurePackageManagerAvailable } 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, showInitFirstMessage } from \"../utils/project-guard\";\n\ntype DatabaseModuleName = \"database-pg\" | \"database-mysql\";\n\nexport interface AddCommandOptions {\n dialect?: string;\n dbUrl?: string;\n yes?: boolean;\n}\n\nconst DEFAULT_DATABASE_URLS: Record<DatabaseModuleName, string> = {\n \"database-pg\": \"postgresql://postgres@localhost:5432/mydb\",\n \"database-mysql\": \"mysql://root@localhost:3306/mydb\",\n};\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\nfunction resolvePackageManager(projectRoot: string) {\n if (fs.existsSync(path.join(projectRoot, \"pnpm-lock.yaml\"))) {\n return \"pnpm\";\n }\n\n if (fs.existsSync(path.join(projectRoot, \"bun.lockb\")) || fs.existsSync(path.join(projectRoot, \"bun.lock\"))) {\n return \"bun\";\n }\n\n if (fs.existsSync(path.join(projectRoot, \"yarn.lock\"))) {\n return \"yarn\";\n }\n\n return \"npm\";\n}\n\nfunction parseDatabaseDialect(value?: string): DatabaseModuleName | null {\n const normalized = value?.trim().toLowerCase();\n if (!normalized) {\n return null;\n }\n\n if (normalized === \"pg\" || normalized === \"postgres\" || normalized === \"postgresql\" || normalized === \"database-pg\") {\n return \"database-pg\";\n }\n\n if (normalized === \"mysql\" || normalized === \"database-mysql\") {\n return \"database-mysql\";\n }\n\n return null;\n}\n\nfunction isDatabaseModule(moduleName: string): moduleName is DatabaseModuleName {\n return moduleName === \"database-pg\" || moduleName === \"database-mysql\";\n}\n\nfunction validateDatabaseUrl(rawUrl: string, moduleName: DatabaseModuleName) {\n const dbUrl = rawUrl.trim();\n if (!dbUrl) {\n throw new Error(\"Database URL cannot be empty.\");\n }\n\n let parsed: URL;\n try {\n parsed = new URL(dbUrl);\n } catch {\n throw new Error(`Invalid database URL: '${dbUrl}'.`);\n }\n\n const protocol = parsed.protocol.toLowerCase();\n if (moduleName === \"database-pg\" && protocol !== \"postgresql:\" && protocol !== \"postgres:\") {\n throw new Error(\"PostgreSQL URL must start with postgres:// or postgresql://\");\n }\n\n if (moduleName === \"database-mysql\" && protocol !== \"mysql:\") {\n throw new Error(\"MySQL URL must start with mysql://\");\n }\n\n return dbUrl;\n}\n\nasync function detectInstalledDatabaseDialect(projectRoot: string, srcDir: string): Promise<DatabaseModuleName | null> {\n const dbIndexPath = path.join(projectRoot, srcDir, \"db\", \"index.ts\");\n if (!fs.existsSync(dbIndexPath)) {\n return null;\n }\n\n const content = await fs.readFile(dbIndexPath, \"utf-8\");\n if (content.includes(\"drizzle-orm/node-postgres\") || content.includes(`from \"pg\"`)) {\n return \"database-pg\";\n }\n\n if (content.includes(\"drizzle-orm/mysql2\") || content.includes(`from \"mysql2`)) {\n return \"database-mysql\";\n }\n\n return null;\n}\n\nasync function backupDatabaseFiles(projectRoot: string, srcDir: string): Promise<string | null> {\n const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const backupRoot = path.join(projectRoot, \".zuro\", \"backups\", `database-${timestamp}`);\n const candidates = [\n path.join(projectRoot, srcDir, \"db\", \"index.ts\"),\n path.join(projectRoot, \"drizzle.config.ts\"),\n ];\n\n let copied = false;\n for (const filePath of candidates) {\n if (!fs.existsSync(filePath)) {\n continue;\n }\n\n const relativePath = path.relative(projectRoot, filePath);\n const backupPath = path.join(backupRoot, relativePath);\n await fs.ensureDir(path.dirname(backupPath));\n await fs.copyFile(filePath, backupPath);\n copied = true;\n }\n\n return copied ? backupRoot : null;\n}\n\nfunction databaseLabel(moduleName: DatabaseModuleName) {\n return moduleName === \"database-pg\" ? \"PostgreSQL\" : \"MySQL\";\n}\n\nfunction getDatabaseSetupHint(moduleName: DatabaseModuleName, dbUrl: string) {\n try {\n const parsed = new URL(dbUrl);\n const dbName = parsed.pathname.replace(/^\\/+/, \"\") || \"mydb\";\n\n if (moduleName === \"database-pg\") {\n return `createdb ${dbName}`;\n }\n\n return `mysql -e \"CREATE DATABASE IF NOT EXISTS ${dbName};\"`;\n } catch {\n return moduleName === \"database-pg\"\n ? \"createdb <database_name>\"\n : `mysql -e \"CREATE DATABASE IF NOT EXISTS <database_name>;\"`;\n }\n}\n\nfunction getModuleDocsPath(moduleName: string) {\n if (isDatabaseModule(moduleName)) {\n return \"database\";\n }\n\n return moduleName;\n}\n\nfunction escapeRegex(value: string) {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nasync function hasEnvVariable(projectRoot: string, key: string): Promise<boolean> {\n const envPath = path.join(projectRoot, \".env\");\n if (!await fs.pathExists(envPath)) {\n return false;\n }\n\n const content = await fs.readFile(envPath, \"utf-8\");\n const pattern = new RegExp(`^${escapeRegex(key)}=`, \"m\");\n return pattern.test(content);\n}\n\nasync function isLikelyEmptyDirectory(cwd: string): Promise<boolean> {\n const entries = await fs.readdir(cwd);\n const ignored = new Set([\".ds_store\", \"thumbs.db\"]);\n\n return entries.filter((entry) => !ignored.has(entry.toLowerCase())).length === 0;\n}\n\nasync function ensureSchemaExport(projectRoot: string, srcDir: string, schemaFileName: string) {\n const schemaIndexPath = path.join(projectRoot, srcDir, \"db\", \"schema\", \"index.ts\");\n if (!await fs.pathExists(schemaIndexPath)) {\n return;\n }\n\n const exportLine = `export * from \"./${schemaFileName}\";`;\n const content = await fs.readFile(schemaIndexPath, \"utf-8\");\n const normalized = content.replace(/\\r\\n/g, \"\\n\");\n const exportPattern = new RegExp(\n `^\\\\s*export\\\\s*\\\\*\\\\s*from\\\\s*[\"']\\\\./${escapeRegex(schemaFileName)}[\"'];?\\\\s*$`,\n \"m\"\n );\n\n if (exportPattern.test(normalized)) {\n return;\n }\n\n let next = normalized\n .replace(/^\\s*export\\s*\\{\\s*\\};?\\s*$/m, \"\")\n .trimEnd();\n\n if (next.length > 0) {\n next += \"\\n\\n\";\n }\n\n next += `${exportLine}\\n`;\n await fs.writeFile(schemaIndexPath, next);\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 const errorImport = `import { errorHandler, notFoundHandler } from \"./middleware/error-handler\";`;\n const hasErrorImport = content.includes(errorImport);\n const hasNotFoundUse = /app\\.use\\(\\s*notFoundHandler\\s*\\)/.test(content);\n const hasErrorUse = /app\\.use\\(\\s*errorHandler\\s*\\)/.test(content);\n let modified = false;\n let importInserted = hasErrorImport;\n\n if (!hasErrorImport) {\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 modified = true;\n importInserted = true;\n }\n }\n\n let setupInserted = hasNotFoundUse && hasErrorUse;\n if (!setupInserted) {\n const setupLines: string[] = [];\n if (!hasNotFoundUse) {\n setupLines.push(\"app.use(notFoundHandler);\");\n }\n\n if (!hasErrorUse) {\n setupLines.push(\"app.use(errorHandler);\");\n }\n\n const errorSetup = `\\n// Error handling (must be last)\\n${setupLines.join(\"\\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) + errorSetup + \"\\n\" + content.slice(exportMatch.index);\n modified = true;\n setupInserted = true;\n }\n }\n\n if (modified) {\n await fs.writeFile(appPath, content);\n }\n\n return importInserted && setupInserted;\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 if (!await fs.pathExists(appPath)) {\n return false;\n }\n\n let appContent = await fs.readFile(appPath, \"utf-8\");\n const authHandlerImport = `import { toNodeHandler } from \"better-auth/node\";`;\n const authImport = `import { auth } from \"./lib/auth\";`;\n const userImport = `import userRoutes from \"./routes/user.routes\";`;\n\n let appModified = false;\n\n const appendImport = (source: string, line: string) => {\n if (source.includes(line)) {\n return { source, inserted: true };\n }\n\n const importRegex = /^import .+ from .+;?\\s*$/gm;\n let lastImportIndex = 0;\n let match;\n while ((match = importRegex.exec(source)) !== null) {\n lastImportIndex = match.index + match[0].length;\n }\n\n if (lastImportIndex <= 0) {\n return { source, inserted: false };\n }\n\n return {\n source: source.slice(0, lastImportIndex) + `\\n${line}` + source.slice(lastImportIndex),\n inserted: true,\n };\n };\n\n for (const importLine of [authHandlerImport, authImport]) {\n const next = appendImport(appContent, importLine);\n if (!next.inserted) {\n return false;\n }\n\n if (next.source !== appContent) {\n appContent = next.source;\n appModified = true;\n }\n }\n\n const hasAuthMount = /toNodeHandler\\(\\s*auth\\s*\\)/.test(appContent)\n && /\\/api\\/auth/.test(appContent);\n if (!hasAuthMount) {\n const authMountLine = \"app.all(/^\\\\/api\\\\/auth(?:\\\\/.*)?$/, toNodeHandler(auth));\\n\";\n const jsonIndex = appContent.search(/^\\s*app\\.use\\(\\s*express\\.json\\(\\)\\s*\\);\\s*$/m);\n\n let insertionIndex = jsonIndex;\n if (insertionIndex < 0) {\n const healthIndex = appContent.search(/^\\s*app\\.get\\(\\s*[\"']\\/health[\"']\\s*,/m);\n insertionIndex = healthIndex;\n }\n\n if (insertionIndex < 0) {\n const exportMatch = appContent.match(/export default app;?\\s*$/m);\n insertionIndex = exportMatch?.index ?? -1;\n }\n\n if (insertionIndex < 0) {\n return false;\n }\n\n appContent = appContent.slice(0, insertionIndex) + authMountLine + appContent.slice(insertionIndex);\n appModified = true;\n }\n\n const routeIndexPath = path.join(projectRoot, srcDir, \"routes\", \"index.ts\");\n if (await fs.pathExists(routeIndexPath)) {\n let routeContent = await fs.readFile(routeIndexPath, \"utf-8\");\n let routeModified = false;\n\n const userImportResult = appendImport(routeContent, userImport);\n if (!userImportResult.inserted) {\n return false;\n }\n\n if (userImportResult.source !== routeContent) {\n routeContent = userImportResult.source;\n routeModified = true;\n }\n\n const hasUserRoute = /rootRouter\\.use\\(\\s*[\"']\\/users[\"']\\s*,\\s*userRoutes\\s*\\)/.test(routeContent);\n if (!hasUserRoute) {\n const routeSetup = `\\n// User routes\\nrootRouter.use(\"/users\", userRoutes);\\n`;\n const exportMatch = routeContent.match(/export default rootRouter;?\\s*$/m);\n\n if (!exportMatch || exportMatch.index === undefined) {\n return false;\n }\n\n routeContent = routeContent.slice(0, exportMatch.index) + routeSetup + \"\\n\" + routeContent.slice(exportMatch.index);\n routeModified = true;\n }\n\n if (routeModified) {\n await fs.writeFile(routeIndexPath, routeContent);\n }\n } else {\n const hasUserRoute = /app\\.use\\(\\s*[\"']\\/api\\/users[\"']\\s*,\\s*userRoutes\\s*\\)/.test(appContent);\n if (!hasUserRoute) {\n const exportMatch = appContent.match(/export default app;?\\s*$/m);\n if (!exportMatch || exportMatch.index === undefined) {\n return false;\n }\n\n const routeSetup = `\\n// User routes\\napp.use(\"/api/users\", userRoutes);\\n`;\n appContent = appContent.slice(0, exportMatch.index) + routeSetup + \"\\n\" + appContent.slice(exportMatch.index);\n appModified = true;\n }\n\n const userImportResult = appendImport(appContent, userImport);\n if (!userImportResult.inserted) {\n return false;\n }\n\n if (userImportResult.source !== appContent) {\n appContent = userImportResult.source;\n appModified = true;\n }\n }\n\n if (appModified) {\n await fs.writeFile(appPath, appContent);\n }\n\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 if (await isLikelyEmptyDirectory(projectRoot)) {\n showInitFirstMessage();\n return;\n }\n\n showNonZuroProjectMessage();\n return;\n }\n const srcDir = projectConfig.srcDir || \"src\";\n let resolvedModuleName = moduleName;\n const parsedDialect = parseDatabaseDialect(moduleName);\n if (parsedDialect) {\n resolvedModuleName = parsedDialect;\n }\n\n let customDbUrl: string | undefined;\n let usedDefaultDbUrl = false;\n let databaseBackupPath: string | null = null;\n let generatedAuthSecret = false;\n let authDatabaseDialect: DatabaseModuleName | null = null;\n\n if (resolvedModuleName === \"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 console.log(chalk.yellow(\"Operation cancelled.\"));\n return;\n }\n\n resolvedModuleName = variantResponse.variant;\n }\n\n if (isDatabaseModule(resolvedModuleName)) {\n const installedDialect = await detectInstalledDatabaseDialect(projectRoot, srcDir);\n\n if (installedDialect && installedDialect !== resolvedModuleName) {\n console.log(\n chalk.yellow(\n `\\n⚠ Existing database setup detected: ${databaseLabel(installedDialect)}.`\n )\n );\n console.log(\n chalk.yellow(\n ` Switching to ${databaseLabel(resolvedModuleName)} will overwrite db files and drizzle config.\\n`\n )\n );\n\n const switchResponse = await prompts({\n type: \"confirm\",\n name: \"proceed\",\n message: \"Continue and switch database dialect?\",\n initial: false,\n });\n\n if (!switchResponse.proceed) {\n console.log(chalk.yellow(\"Operation cancelled.\"));\n return;\n }\n\n databaseBackupPath = await backupDatabaseFiles(projectRoot, srcDir);\n }\n\n const defaultUrl = DEFAULT_DATABASE_URLS[resolvedModuleName];\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\n if (response.dbUrl === undefined) {\n console.log(chalk.yellow(\"Operation cancelled.\"));\n return;\n }\n\n const enteredUrl = response.dbUrl?.trim() || \"\";\n usedDefaultDbUrl = enteredUrl.length === 0;\n customDbUrl = validateDatabaseUrl(enteredUrl || defaultUrl, resolvedModuleName);\n }\n\n const pm = resolvePackageManager(projectRoot);\n const spinner = ora(`Checking registry for ${resolvedModuleName}...`).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 = `Checking registry for ${resolvedModuleName}...`;\n const registryContext = await fetchRegistry();\n const module = registryContext.manifest.modules[resolvedModuleName];\n\n if (!module) {\n spinner.fail(`Module '${resolvedModuleName}' not found.`);\n return;\n }\n\n spinner.succeed(`Found module: ${chalk.cyan(resolvedModuleName)}`);\n\n const moduleDeps = module.moduleDependencies || [];\n currentStep = \"module dependency resolution\";\n await resolveDependencies(moduleDeps, projectRoot);\n\n currentStep = \"dependency installation\";\n spinner.start(\"Installing dependencies...\");\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 currentStep = \"module scaffolding\";\n spinner.start(\"Scaffolding files...\");\n\n if (resolvedModuleName === \"auth\") {\n authDatabaseDialect = await detectInstalledDatabaseDialect(projectRoot, srcDir);\n }\n\n for (const file of module.files) {\n let fetchPath = file.path;\n let expectedSha256 = file.sha256;\n let expectedSize = file.size;\n\n if (\n resolvedModuleName === \"auth\"\n && file.target === \"db/schema/auth.ts\"\n && authDatabaseDialect === \"database-mysql\"\n ) {\n fetchPath = \"express/db/schema/auth.mysql.ts\";\n expectedSha256 = undefined;\n expectedSize = undefined;\n }\n\n let content = await fetchFile(fetchPath, {\n baseUrl: registryContext.fileBaseUrl,\n expectedSha256,\n expectedSize,\n });\n\n if (isDatabaseModule(resolvedModuleName) && file.target === \"../drizzle.config.ts\") {\n const normalizedSrcDir = srcDir.replace(/\\\\/g, \"/\");\n content = content.replace(\n /schema:\\s*[\"'][^\"']+[\"']/,\n `schema: \"./${normalizedSrcDir}/db/schema/*\"`\n );\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 const schemaExports = module.files\n .map((file) => file.target.replace(/\\\\/g, \"/\"))\n .filter((target) => /^db\\/schema\\/[^/]+\\.ts$/.test(target))\n .map((target) => path.posix.basename(target, \".ts\"))\n .filter((name) => name !== \"index\");\n\n for (const schemaFileName of schemaExports) {\n await ensureSchemaExport(projectRoot, srcDir, schemaFileName);\n }\n\n spinner.succeed(\"Files generated\");\n\n if (resolvedModuleName === \"auth\") {\n spinner.start(\"Configuring routes...\");\n const injected = await injectAuthRoutes(projectRoot, srcDir);\n if (injected) {\n spinner.succeed(\"Routes configured\");\n } else {\n spinner.warn(\"Could not configure routes automatically\");\n }\n }\n\n if (resolvedModuleName === \"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[resolvedModuleName as keyof typeof ENV_CONFIGS];\n if (envConfig) {\n currentStep = \"environment configuration\";\n spinner.start(\"Updating environment configuration...\");\n\n const envVars: Record<string, string> = { ...envConfig.envVars };\n if (customDbUrl && isDatabaseModule(resolvedModuleName)) {\n envVars.DATABASE_URL = customDbUrl;\n }\n\n if (resolvedModuleName === \"auth\") {\n const hasExistingSecret = await hasEnvVariable(projectRoot, \"BETTER_AUTH_SECRET\");\n if (!hasExistingSecret) {\n envVars.BETTER_AUTH_SECRET = randomBytes(32).toString(\"hex\");\n generatedAuthSecret = true;\n }\n }\n\n await updateEnvFile(projectRoot, envVars, true, {\n overwriteExisting: isDatabaseModule(resolvedModuleName),\n });\n await updateEnvSchema(projectRoot, srcDir, envConfig.schemaFields);\n\n spinner.succeed(\"Environment configured\");\n }\n\n console.log(chalk.green(`\\n✔ ${resolvedModuleName} added successfully!\\n`));\n\n if (databaseBackupPath) {\n console.log(chalk.blue(`ℹ Backup created at: ${databaseBackupPath}\\n`));\n }\n\n const docsPath = getModuleDocsPath(resolvedModuleName);\n const docsUrl = `https://zuro-cli.devbybriyan.com/docs/${docsPath}`;\n console.log(chalk.blue(`ℹ Docs: ${docsUrl}`));\n\n if (isDatabaseModule(resolvedModuleName)) {\n if (usedDefaultDbUrl) {\n console.log(chalk.yellow(\"ℹ Review DATABASE_URL in .env if your local DB config differs.\"));\n }\n\n const setupHint = getDatabaseSetupHint(\n resolvedModuleName,\n customDbUrl || DEFAULT_DATABASE_URLS[resolvedModuleName]\n );\n console.log(chalk.yellow(`ℹ Ensure DB exists: ${setupHint}`));\n console.log(chalk.yellow(\"ℹ Run migrations: npx drizzle-kit generate && npx drizzle-kit migrate\"));\n }\n\n if (resolvedModuleName === \"auth\") {\n if (generatedAuthSecret) {\n console.log(chalk.yellow(\"ℹ BETTER_AUTH_SECRET was generated automatically.\"));\n } else {\n console.log(chalk.yellow(\"ℹ Review BETTER_AUTH_SECRET and BETTER_AUTH_URL in .env.\"));\n }\n\n console.log(chalk.yellow(\"ℹ Run migrations: npx drizzle-kit generate && npx drizzle-kit migrate\"));\n }\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 console.log(chalk.cyan(` npx zuro-cli add ${resolvedModuleName}`));\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":";;;;;;;;;;;;;;;;;;;;;;;;;;AACA,uBAAwB;;;ACDxB,iBAAgB;AAChB,IAAAA,gBAAkB;AAClB,IAAAC,mBAAe;AACf,IAAAC,eAAiB;AACjB,qBAAoB;;;ACJpB,yBAA2B;AAE3B,IAAM,4BAA4B;AAClC,IAAM,6BAA6B,GAAG,yBAAyB;AAC/D,IAAM,mBAAmB;AACzB,IAAM,qBAAqB;AAC3B,IAAM,cAAc;AAmDpB,SAAS,kBAAkB,KAAa;AACtC,SAAO,IAAI,SAAS,GAAG,IAAI,MAAM,GAAG,GAAG;AACzC;AAEA,SAAS,0BAA0B;AACjC,QAAM,WAAW,QAAQ,IAAI,gBAAgB,GAAG,KAAK;AAErD,MAAI,CAAC,UAAU;AACb,WAAO;AAAA,EACT;AAEA,MAAI;AAEJ,MAAI;AACF,aAAS,IAAI,IAAI,QAAQ;AAAA,EAC3B,QAAQ;AACN,UAAM,IAAI;AAAA,MACR,WAAW,gBAAgB,WAAW,QAAQ;AAAA,IAChD;AAAA,EACF;AAEA,MAAI,OAAO,SAAS,SAAS,OAAO,GAAG;AACrC,WAAO,OAAO,SAAS;AAAA,EACzB;AAEA,SAAO,IAAI,IAAI,wBAAwB,kBAAkB,OAAO,SAAS,CAAC,CAAC,EAAE,SAAS;AACxF;AAEA,SAAS,mBAAmB,MAAyC;AACnE,MAAI,CAAC,QAAQ,OAAO,SAAS,UAAU;AACrC,WAAO;AAAA,EACT;AAEA,QAAM,YAAY;AAClB,SAAO,CAAC,CAAC,UAAU,WAAW,OAAO,UAAU,YAAY;AAC7D;AAEA,SAAS,iBAAiB,MAA+C;AACvE,MAAI,CAAC,QAAQ,OAAO,SAAS,UAAU;AACrC,WAAO;AAAA,EACT;AAEA,QAAM,YAAY;AAClB,SAAO,OAAO,UAAU,cAAc,YAAY,OAAO,UAAU,aAAa;AAClF;AAEA,SAAS,MAAM,IAAY;AACzB,SAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AACzD;AAEA,eAAe,eAAe,KAAgC;AAC5D,MAAI;AAEJ,WAAS,UAAU,GAAG,WAAW,aAAa,WAAW;AACvD,UAAM,aAAa,IAAI,gBAAgB;AACvC,UAAM,UAAU,WAAW,MAAM,WAAW,MAAM,GAAG,kBAAkB;AAEvE,QAAI;AACF,YAAM,WAAW,MAAM,MAAM,KAAK;AAAA,QAChC,SAAS,EAAE,QAAQ,oCAAoC;AAAA,QACvD,QAAQ,WAAW;AAAA,MACrB,CAAC;AAED,UAAI,SAAS,IAAI;AACf,eAAO;AAAA,MACT;AAEA,YAAM,cAAc,SAAS,UAAU,OAAO,UAAU;AACxD,UAAI,aAAa;AACf,cAAM,MAAM,OAAO,UAAU,EAAE;AAC/B;AAAA,MACF;AAEA,YAAM,IAAI,MAAM,mBAAmB,SAAS,MAAM,IAAI,SAAS,UAAU,SAAS,GAAG,EAAE;AAAA,IACzF,SAAS,OAAO;AACd,kBAAY;AAEZ,UAAI,YAAY,aAAa;AAC3B;AAAA,MACF;AAEA,YAAM,MAAM,OAAO,UAAU,EAAE;AAAA,IACjC,UAAE;AACA,mBAAa,OAAO;AAAA,IACtB;AAAA,EACF;AAEA,MAAI,qBAAqB,OAAO;AAC9B,UAAM;AAAA,EACR;AAEA,QAAM,IAAI,MAAM,mBAAmB,GAAG,EAAE;AAC1C;AAEA,eAAe,UAAa,KAAwD;AAClF,QAAM,WAAW,MAAM,eAAe,GAAG;AACzC,QAAM,OAAQ,MAAM,SAAS,KAAK;AAElC,SAAO;AAAA,IACL;AAAA,IACA,aAAa,SAAS,OAAO;AAAA,EAC/B;AACF;AAEA,SAAS,mBAAmB,SAAiC,YAA4B;AACvF,QAAM,WAAW,QAAQ,YAAY,QAAQ;AAE7C,MAAI,CAAC,UAAU;AACb,UAAM,IAAI,MAAM,wDAAwD;AAAA,EAC1E;AAEA,SAAO,IAAI,IAAI,UAAU,UAAU,EAAE,SAAS;AAChD;AAEA,eAAsB,gBAA0C;AAC9D,QAAM,mBAAmB,wBAAwB;AACjD,MAAI;AAEJ,MAAI;AACF,YAAQ,MAAM,UAAmB,gBAAgB;AAAA,EACnD,SAAS,OAAO;AACd,UAAM,IAAI;AAAA,MACR,iCAAiC,gBAAgB,2BAA2B,gBAAgB;AAAA,MAC5F,EAAE,OAAO,MAAe;AAAA,IAC1B;AAAA,EACF;AAEA,MAAI,mBAAmB,MAAM,IAAI,GAAG;AAClC,WAAO;AAAA,MACL,UAAU,MAAM;AAAA,MAChB,aAAa,MAAM;AAAA,MACnB,aAAa,kBAAkB,IAAI,IAAI,KAAK,MAAM,WAAW,EAAE,SAAS,CAAC;AAAA,IAC3E;AAAA,EACF;AAEA,MAAI,CAAC,iBAAiB,MAAM,IAAI,GAAG;AACjC,UAAM,IAAI;AAAA,MACR,+BAA+B,gBAAgB;AAAA,IACjD;AAAA,EACF;AAEA,QAAM,cAAc,mBAAmB,MAAM,MAAM,MAAM,WAAW;AACpE,QAAM,iBAAiB,MAAM,UAAmB,WAAW;AAE3D,MAAI,CAAC,mBAAmB,eAAe,IAAI,GAAG;AAC5C,UAAM,IAAI,MAAM,+BAA+B,WAAW,GAAG;AAAA,EAC/D;AAEA,SAAO;AAAA,IACL,UAAU,eAAe;AAAA,IACzB,aAAa,eAAe;AAAA,IAC5B,aAAa,kBAAkB,IAAI,IAAI,KAAK,eAAe,WAAW,EAAE,SAAS,CAAC;AAAA,EACpF;AACF;AAEA,eAAsB,UAAU,UAAkB,SAA2B;AAC3E,QAAM,iBAAiB,SAAS,QAAQ,OAAO,EAAE;AACjD,QAAM,UAAU,IAAI,IAAI,gBAAgB,kBAAkB,QAAQ,OAAO,CAAC,EAAE,SAAS;AACrF,QAAM,WAAW,MAAM,eAAe,OAAO;AAC7C,QAAM,UAAU,MAAM,SAAS,KAAK;AAEpC,MAAI,OAAO,QAAQ,iBAAiB,UAAU;AAC5C,UAAM,aAAa,OAAO,WAAW,SAAS,MAAM;AACpD,QAAI,eAAe,QAAQ,cAAc;AACvC,YAAM,IAAI;AAAA,QACR,qBAAqB,QAAQ,cAAc,QAAQ,YAAY,SAAS,UAAU;AAAA,MACpF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,QAAQ,gBAAgB;AAC1B,UAAM,mBAAe,+BAAW,QAAQ,EAAE,OAAO,SAAS,MAAM,EAAE,OAAO,KAAK;AAC9E,QAAI,iBAAiB,QAAQ,gBAAgB;AAC3C,YAAM,IAAI;AAAA,QACR,yBAAyB,QAAQ,cAAc,QAAQ,cAAc,SAAS,YAAY;AAAA,MAC5F;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AACT;;;AC7OA,sBAAe;AACf,kBAAiB;AACjB,mBAAsB;AAEtB,SAAS,qBAAqB,MAAc;AACxC,QAAM,aAAa,KACd,KAAK,EACL,YAAY,EACZ,QAAQ,iBAAiB,GAAG,EAC5B,QAAQ,OAAO,GAAG,EAClB,QAAQ,oBAAoB,EAAE;AAEnC,SAAO,cAAc;AACzB;AAEA,eAAsB,8BAA8B,IAAY;AAC5D,MAAI;AACA,cAAM,oBAAM,IAAI,CAAC,WAAW,GAAG,EAAE,OAAO,SAAS,CAAC;AAAA,EACtD,QAAQ;AACJ,UAAM,IAAI;AAAA,MACN,oBAAoB,EAAE;AAAA,IAC1B;AAAA,EACJ;AACJ;AAEA,eAAsB,gBAClB,KACA,QAAiB,OACjB,cAAc,YACd,SAAS,OACT,UAAwC,CAAC,GAC3C;AACE,QAAM,UAAU,YAAAC,QAAK,KAAK,KAAK,cAAc;AAC7C,MAAI,SAAS,CAAC,MAAM,gBAAAC,QAAG,WAAW,OAAO,GAAG;AACxC,UAAM,UAAkC;AAAA,MACpC,OAAO,aAAa,MAAM;AAAA,MAC1B,SAAS;AAAA,MACT,SAAS;AAAA,IACb;AAEA,QAAI,QAAQ,gBAAgB;AACxB,cAAQ,QAAQ,IAAI;AACpB,cAAQ,cAAc,IAAI;AAAA,IAC9B;AAEA,UAAM,gBAAAA,QAAG,UAAU,SAAS;AAAA,MACxB,MAAM,qBAAqB,WAAW;AAAA,MACtC,SAAS;AAAA,MACT,SAAS;AAAA,MACT;AAAA,IACJ,GAAG,EAAE,QAAQ,EAAE,CAAC;AAAA,EACpB;AACJ;AAMA,eAAsB,oBAClB,IACA,MACA,KACA,UAA0B,CAAC,GAC7B;AACE,QAAM,aAAa,CAAC,GAAG,IAAI,IAAI,IAAI,CAAC,EAAE,OAAO,OAAO;AAEpD,MAAI,WAAW,WAAW,GAAG;AACzB;AAAA,EACJ;AAEA,QAAM,QAAQ,QAAQ,OAAO;AAE7B,MAAI,OAAO,OAAO;AACd,UAAM,OAAO,CAAC,WAAW,GAAI,QAAQ,CAAC,YAAY,IAAI,CAAC,GAAI,GAAG,UAAU;AACxE,cAAM,oBAAM,OAAO,MAAM,EAAE,IAAI,CAAC;AAChC;AAAA,EACJ;AAEA,MAAI,OAAO,QAAQ;AACf,UAAM,OAAO,CAAC,OAAO,GAAI,QAAQ,CAAC,IAAI,IAAI,CAAC,GAAI,GAAG,UAAU;AAC5D,cAAM,oBAAM,QAAQ,MAAM,EAAE,IAAI,CAAC;AACjC;AAAA,EACJ;AAEA,MAAI,OAAO,QAAQ;AACf,UAAM,OAAO,CAAC,OAAO,GAAI,QAAQ,CAAC,IAAI,IAAI,CAAC,GAAI,GAAG,UAAU;AAC5D,cAAM,oBAAM,QAAQ,MAAM,EAAE,IAAI,CAAC;AACjC;AAAA,EACJ;AAEA,MAAI,OAAO,OAAO;AACd,UAAM,OAAO,CAAC,OAAO,GAAI,QAAQ,CAAC,IAAI,IAAI,CAAC,GAAI,GAAG,UAAU;AAC5D,cAAM,oBAAM,OAAO,MAAM,EAAE,IAAI,CAAC;AAChC;AAAA,EACJ;AAEA,QAAM,IAAI,MAAM,gCAAgC,EAAE,EAAE;AACxD;;;ACjGA,IAAAC,mBAAe;AACf,IAAAC,eAAiB;AACjB,gBAAe;AAKR,IAAM,gBAAgB,OACzB,KACA,WACA,kBAAkB,MAClB,UAA2C,CAAC,MAC3C;AACD,QAAM,UAAU,aAAAC,QAAK,KAAK,KAAK,MAAM;AACrC,QAAM,oBAAoB,QAAQ,qBAAqB;AAEvD,MAAI,UAAU;AACd,MAAI,iBAAAC,QAAG,WAAW,OAAO,GAAG;AACxB,cAAU,MAAM,iBAAAA,QAAG,SAAS,SAAS,OAAO;AAAA,EAChD,WAAW,CAAC,iBAAiB;AACzB;AAAA,EACJ;AAEA,MAAI,WAAW;AAEf,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,SAAS,GAAG;AAClD,UAAM,aAAa,IAAI,QAAQ,uBAAuB,MAAM;AAC5D,UAAM,QAAQ,IAAI,OAAO,IAAI,UAAU,QAAQ,GAAG;AAElD,QAAI,MAAM,KAAK,OAAO,GAAG;AACrB,UAAI,CAAC,mBAAmB;AACpB;AAAA,MACJ;AAEA,YAAM,WAAW,GAAG,GAAG,IAAI,KAAK;AAChC,YAAM,UAAU,QAAQ,QAAQ,OAAO,QAAQ;AAC/C,UAAI,YAAY,SAAS;AACrB,kBAAU;AACV,mBAAW;AAAA,MACf;AACA;AAAA,IACJ;AAGA,QAAI,WAAW,CAAC,QAAQ,SAAS,IAAI,GAAG;AACpC,iBAAW,UAAAC,QAAG;AAAA,IAClB;AACA,eAAW,GAAG,GAAG,IAAI,KAAK,GAAG,UAAAA,QAAG,GAAG;AACnC,eAAW;AAAA,EACf;AAEA,MAAI,YAAY,CAAC,iBAAAD,QAAG,WAAW,OAAO,GAAG;AACrC,UAAM,iBAAAA,QAAG,UAAU,SAAS,OAAO;AAAA,EACvC;AACJ;AAKO,IAAM,kBAAkB,OAC3B,KACA,QACA,WACC;AACD,QAAM,UAAU,aAAAD,QAAK,KAAK,KAAK,QAAQ,QAAQ;AAE/C,MAAI,CAAC,iBAAAC,QAAG,WAAW,OAAO,GAAG;AACzB,WAAO;AAAA,EACX;AAEA,MAAI,UAAU,MAAM,iBAAAA,QAAG,SAAS,SAAS,OAAO;AAChD,MAAI,WAAW;AAEf,aAAW,SAAS,QAAQ;AAExB,QAAI,QAAQ,SAAS,GAAG,MAAM,IAAI,GAAG,GAAG;AACpC;AAAA,IACJ;AAIA,UAAM,iBAAiB;AACvB,UAAM,QAAQ,QAAQ,MAAM,cAAc;AAE1C,QAAI,OAAO;AACP,YAAM,SAAS;AACf,YAAM,WAAW,GAAG,MAAM,GAAG,MAAM,IAAI,KAAK,MAAM,MAAM;AAAA;AACxD,gBAAU,QAAQ;AAAA,QACd;AAAA,QACA;AAAA,EAAK,QAAQ;AAAA,MACjB;AACA,iBAAW;AAAA,IACf;AAAA,EACJ;AAEA,MAAI,UAAU;AACV,UAAM,iBAAAA,QAAG,UAAU,SAAS,OAAO;AAAA,EACvC;AAEA,SAAO;AACX;AAKO,IAAM,mBAAmB,OAAO,QAAgB;AACnD,QAAM,UAAU,aAAAD,QAAK,KAAK,KAAK,MAAM;AAErC,MAAI,iBAAAC,QAAG,WAAW,OAAO,GAAG;AACxB;AAAA,EACJ;AAEA,QAAM,UAAU;AAAA;AAAA;AAAA;AAKhB,QAAM,iBAAAA,QAAG,UAAU,SAAS,OAAO;AACvC;AAKO,IAAM,cAAc;AAAA,EACvB,eAAe;AAAA,IACX,SAAS;AAAA,MACL,cAAc;AAAA,IAClB;AAAA,IACA,cAAc;AAAA,MACV,EAAE,MAAM,gBAAgB,QAAQ,mBAAmB;AAAA,IACvD;AAAA,EACJ;AAAA,EACA,kBAAkB;AAAA,IACd,SAAS;AAAA,MACL,cAAc;AAAA,IAClB;AAAA,IACA,cAAc;AAAA,MACV,EAAE,MAAM,gBAAgB,QAAQ,mBAAmB;AAAA,IACvD;AAAA,EACJ;AAAA,EACA,MAAM;AAAA,IACF,SAAS;AAAA,MACL,oBAAoB;AAAA,MACpB,iBAAiB;AAAA,IACrB;AAAA,IACA,cAAc;AAAA,MACV,EAAE,MAAM,sBAAsB,QAAQ,qBAAqB;AAAA,MAC3D,EAAE,MAAM,mBAAmB,QAAQ,mBAAmB;AAAA,IAC1D;AAAA,EACJ;AACJ;;;ACtJA,IAAAE,mBAAe;AACf,IAAAC,eAAiB;AAQjB,SAAS,eAAe,OAA4B;AAClD,MAAI,CAAC,SAAS,OAAO,UAAU,UAAU;AACvC,WAAO,CAAC;AAAA,EACV;AAEA,QAAM,MAAM;AACZ,QAAM,SAAqB,CAAC;AAE5B,MAAI,OAAO,IAAI,SAAS,UAAU;AAChC,WAAO,OAAO,IAAI;AAAA,EACpB;AAEA,MAAI,OAAO,IAAI,OAAO,UAAU;AAC9B,WAAO,KAAK,IAAI;AAAA,EAClB;AAEA,MAAI,OAAO,IAAI,WAAW,UAAU;AAClC,WAAO,SAAS,IAAI;AAAA,EACtB;AAEA,SAAO;AACT;AAEO,SAAS,cAAc,KAAa;AACzC,SAAO,aAAAC,QAAK,KAAK,KAAK,WAAW;AACnC;AAEA,eAAsB,eAAe,KAAyC;AAC5E,QAAM,aAAa,cAAc,GAAG;AAEpC,MAAI,CAAE,MAAM,iBAAAC,QAAG,WAAW,UAAU,GAAI;AACtC,WAAO;AAAA,EACT;AAEA,QAAM,MAAM,MAAM,iBAAAA,QAAG,SAAS,UAAU;AACxC,SAAO,eAAe,GAAG;AAC3B;AAEA,eAAsB,gBAAgB,KAAa,QAAoB;AACrE,QAAM,aAAa,cAAc,GAAG;AACpC,QAAM,iBAAAA,QAAG,UAAU,YAAY,eAAe,MAAM,GAAG,EAAE,QAAQ,EAAE,CAAC;AACtE;;;AClDA,mBAAkB;AAEX,SAAS,4BAA4B;AACxC,UAAQ,IAAI,aAAAC,QAAM,OAAO,kFAAkF,CAAC;AAC5G,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,aAAAA,QAAM,OAAO,oFAAoF,CAAC;AAC9G,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,oBAAoB;AAChC,UAAQ,IAAI,+BAA+B;AAC3C,UAAQ,IAAI,oDAAoD;AACpE;AAEO,SAAS,uBAAuB;AACnC,UAAQ,IAAI,aAAAA,QAAM,OAAO,0CAA0C,CAAC;AACpE,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,aAAAA,QAAM,OAAO,mCAAmC,CAAC;AAC7D,UAAQ,IAAI,EAAE;AACd,UAAQ,IAAI,aAAAA,QAAM,KAAK,mBAAmB,CAAC;AAC/C;;;ALNA,SAAS,sBAAsB,aAAqB,QAAgB,MAAoB;AACpF,QAAM,qBAAqB,aAAAC,QAAK,KAAK,QAAQ,KAAK,MAAM;AACxD,QAAM,aAAa,aAAAA,QAAK,QAAQ,aAAa,kBAAkB;AAC/D,QAAM,iBAAiB,aAAAA,QAAK,QAAQ,WAAW;AAE/C,MAAI,eAAe,kBAAkB,CAAC,WAAW,WAAW,GAAG,cAAc,GAAG,aAAAA,QAAK,GAAG,EAAE,GAAG;AACzF,UAAM,IAAI,MAAM,gDAAgD,KAAK,MAAM,EAAE;AAAA,EACjF;AAEA,SAAO;AAAA,IACH;AAAA,IACA;AAAA,EACJ;AACJ;AAEA,eAAe,0BAA0B,WAAmB,KAAa,aAAqB;AAC1F,QAAM,iBAAAC,QAAG,UAAU,SAAS;AAC5B,QAAM,UAAU,MAAM,iBAAAA,QAAG,QAAQ,SAAS;AAE1C,MAAI,QAAQ,WAAW,GAAG;AACtB,WAAO;AAAA,EACX;AAEA,QAAM,kBAAkB,cAAc;AACtC,QAAM,WAAW,UAAM,eAAAC,SAAQ;AAAA,IAC3B,MAAM;AAAA,IACN,MAAM;AAAA,IACN,SAAS,kBACH,mBAAmB,WAAW,qCAC9B,kBAAkB,WAAW;AAAA,IACnC,SAAS;AAAA,EACb,CAAC;AAED,SAAO,SAAS,YAAY;AAChC;AAEA,eAAe,cAAc,WAAmB;AAC5C,QAAM,qBAAqB,aAAAF,QAAK,KAAK,WAAW,aAAa;AAC7D,QAAM,qBAAqB,aAAAA,QAAK,KAAK,WAAW,iBAAiB;AAEjE,MAAI,CAAC,MAAM,iBAAAC,QAAG,WAAW,kBAAkB,GAAG;AAC1C,UAAM,iBAAiB;AAAA,MACnB,MAAM;AAAA,MACN,aAAa;AAAA,MACb,eAAe;AAAA,MACf,YAAY;AAAA,MACZ,UAAU;AAAA,IACd;AACA,UAAM,iBAAAA,QAAG,UAAU,oBAAoB,gBAAgB,EAAE,QAAQ,EAAE,CAAC;AAAA,EACxE;AAEA,MAAI,CAAC,MAAM,iBAAAA,QAAG,WAAW,kBAAkB,GAAG;AAC1C,UAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAUtB,UAAM,iBAAAA,QAAG,UAAU,oBAAoB,aAAa;AAAA,EACxD;AACJ;AAEA,eAAsB,OAAO;AACzB,QAAM,MAAM,QAAQ,IAAI;AACxB,QAAM,oBAAoB,MAAM,iBAAAA,QAAG,WAAW,aAAAD,QAAK,KAAK,KAAK,cAAc,CAAC;AAC5E,QAAM,qBAAqB,MAAM,eAAe,GAAG;AAEnD,MAAI,qBAAqB,CAAC,oBAAoB;AAC1C,8BAA0B;AAC1B;AAAA,EACJ;AAEA,MAAI,YAAY;AAChB,MAAI,KAAK;AACT,MAAI,SAAS;AACb,MAAI,cAAc,aAAAA,QAAK,SAAS,GAAG;AACnC,MAAI,iBAAiB;AAErB,MAAI,mBAAmB;AACnB,YAAQ,IAAI,cAAAG,QAAM,KAAK,mCAA8B,CAAC;AAEtD,kBAAc,aAAAH,QAAK,SAAS,GAAG;AAE/B,QAAI,MAAM,iBAAAC,QAAG,WAAW,aAAAD,QAAK,KAAK,KAAK,gBAAgB,CAAC,GAAG;AACvD,WAAK;AAAA,IACT,WAAW,MAAM,iBAAAC,QAAG,WAAW,aAAAD,QAAK,KAAK,KAAK,WAAW,CAAC,GAAG;AACzD,WAAK;AAAA,IACT,WAAW,MAAM,iBAAAC,QAAG,WAAW,aAAAD,QAAK,KAAK,KAAK,WAAW,CAAC,GAAG;AACzD,WAAK;AAAA,IACT;AAEA,UAAM,WAAW,UAAM,eAAAE,SAAQ;AAAA,MAC3B,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,IACb,CAAC;AAED,aAAS,SAAS,UAAU;AAAA,EAChC,OAAO;AACH,YAAQ,IAAI,cAAAC,QAAM,IAAI,6CAA6C,aAAAH,QAAK,SAAS,GAAG,CAAC;AAAA,CAAK,CAAC;AAE3F,UAAM,WAAW,UAAM,eAAAE,SAAQ;AAAA,MAC3B;AAAA,QACI,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,MACb;AAAA,MACA;AAAA,QACI,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,UACL,EAAE,OAAO,OAAO,OAAO,MAAM;AAAA,UAC7B,EAAE,OAAO,QAAQ,OAAO,OAAO;AAAA,UAC/B,EAAE,OAAO,OAAO,OAAO,MAAM;AAAA,QACjC;AAAA,QACA,SAAS;AAAA,MACb;AAAA,MACA;AAAA,QACI,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,MACb;AAAA,IACJ,CAAC;AAED,QAAI,SAAS,OAAO,QAAW;AAC3B,cAAQ,IAAI,cAAAC,QAAM,IAAI,sBAAsB,CAAC;AAC7C;AAAA,IACJ;AAEA,SAAK,SAAS;AACd,qBAAiB,SAAS,aAAa;AACvC,aAAS;AAET,QAAI,CAAC,SAAS,QAAQ,SAAS,KAAK,KAAK,MAAM,IAAI;AAC/C,oBAAc,aAAAH,QAAK,SAAS,GAAG;AAC/B,kBAAY;AACZ,cAAQ,IAAI,cAAAG,QAAM,KAAK,gCAA2B,WAAW,EAAE,CAAC;AAAA,IACpE,OAAO;AACH,oBAAc,SAAS,KAAK,KAAK;AACjC,kBAAY,aAAAH,QAAK,QAAQ,KAAK,WAAW;AAAA,IAC7C;AAEA,UAAM,eAAe,MAAM,0BAA0B,WAAW,KAAK,WAAW;AAChF,QAAI,CAAC,cAAc;AACf,cAAQ,IAAI,cAAAG,QAAM,IAAI,sBAAsB,CAAC;AAC7C;AAAA,IACJ;AAAA,EACJ;AAEA,QAAM,iBAAiB,cAAc,MAAM,qBAAqB,MAAM,eAAe,SAAS;AAE9F,QAAM,aAAyB;AAAA,IAC3B,MAAM;AAAA,IACN;AAAA,IACA,QAAQ,UAAU,gBAAgB,UAAU;AAAA,EAChD;AAEA,QAAM,cAAU,WAAAC,SAAI,gCAAgC,EAAE,MAAM;AAC5D,MAAI,cAAc;AAElB,MAAI;AACA,YAAQ,OAAO,YAAY,EAAE;AAC7B,UAAM,8BAA8B,EAAE;AAEtC,kBAAc;AACd,YAAQ,OAAO;AACf,UAAM,kBAAkB,MAAM,cAAc;AAE5C,UAAM,aAAa,gBAAgB,SAAS,QAAQ;AAEpD,QAAI,CAAC,YAAY;AACb,cAAQ,KAAK,oCAAoC;AACjD;AAAA,IACJ;AAEA,kBAAc;AACd,YAAQ,OAAO;AAEf,UAAM,iBAAiB,MAAM,iBAAAH,QAAG,WAAW,aAAAD,QAAK,KAAK,WAAW,cAAc,CAAC;AAC/E,QAAI,CAAC,gBAAgB;AACjB,YAAM,gBAAgB,WAAW,MAAM,aAAa,QAAQ,EAAE,eAAe,CAAC;AAAA,IAClF;AAEA,kBAAc;AACd,YAAQ,OAAO,iCAAiC,EAAE;AAElD,QAAI,cAAwB,CAAC;AAC7B,QAAI,UAAoB,CAAC;AAEzB,QAAI,mBAAmB;AACnB,YAAM,WAAW,CAAC,OAAO,QAAQ;AACjC,YAAM,WAAW,WAAW,gBAAgB,CAAC;AAC7C,oBAAc,SAAS,OAAO,CAAC,eAAe,SAAS,SAAS,UAAU,CAAC;AAC3E,gBAAU,WAAW,mBAAmB,CAAC;AAAA,IAC7C,OAAO;AACH,oBAAc,WAAW,gBAAgB,CAAC;AAC1C,gBAAU,WAAW,mBAAmB,CAAC;AAAA,IAC7C;AAEA,UAAM,oBAAoB,IAAI,aAAa,SAAS;AACpD,UAAM,oBAAoB,IAAI,SAAS,WAAW,EAAE,KAAK,KAAK,CAAC;AAE/D,QAAI,gBAAgB;AAChB,YAAM,oBAAoB,IAAI,CAAC,UAAU,GAAG,WAAW,EAAE,KAAK,KAAK,CAAC;AAAA,IACxE;AAEA,kBAAc;AACd,YAAQ,OAAO;AAEf,eAAW,QAAQ,WAAW,OAAO;AACjC,YAAM,EAAE,oBAAoB,WAAW,IAAI,sBAAsB,WAAW,QAAQ,IAAI;AACxF,YAAM,WAAW,aAAAA,QAAK,SAAS,UAAU;AAEzC,UAAI,mBAAmB;AACnB,YAAI,aAAa,YAAY,aAAa,aAAa;AACnD;AAAA,QACJ;AAEA,cAAM,gBAAgB,mBAAmB,MAAM,aAAAA,QAAK,GAAG;AACvD,cAAM,SAAS,aAAa,YAAY,cAAc,SAAS,KAAK;AACpE,YAAI,CAAC,QAAQ;AACT;AAAA,QACJ;AAAA,MACJ;AAEA,YAAM,UAAU,MAAM,UAAU,KAAK,MAAM;AAAA,QACvC,SAAS,gBAAgB;AAAA,QACzB,gBAAgB,KAAK;AAAA,QACrB,cAAc,KAAK;AAAA,MACvB,CAAC;AAED,YAAM,iBAAAC,QAAG,UAAU,aAAAD,QAAK,QAAQ,UAAU,CAAC;AAC3C,YAAM,iBAAAC,QAAG,UAAU,YAAY,OAAO;AAAA,IAC1C;AAEA,kBAAc;AACd,UAAM,iBAAiB,SAAS;AAEhC,QAAI,gBAAgB;AAChB,oBAAc;AACd,YAAM,cAAc,SAAS;AAAA,IACjC;AAEA,kBAAc;AACd,UAAM,gBAAgB,WAAW,UAAU;AAE3C,YAAQ,QAAQ,cAAAE,QAAM,MAAM,mCAAmC,CAAC;AAEhE,YAAQ,IAAI;AAAA,EAAK,cAAAA,QAAM,KAAK,aAAa,CAAC,EAAE;AAC5C,QAAI,cAAc,KAAK;AACnB,cAAQ,IAAI,cAAAA,QAAM,KAAK,QAAQ,WAAW,EAAE,CAAC;AAAA,IACjD;AACA,YAAQ,IAAI,cAAAA,QAAM,KAAK,KAAK,EAAE,UAAU,CAAC;AACzC,YAAQ,IAAI;AAAA,EAAK,cAAAA,QAAM,IAAI,uDAAuD,CAAC,EAAE;AAAA,EACzF,SAAS,OAAO;AACZ,YAAQ,KAAK,cAAAA,QAAM,IAAI,iBAAiB,WAAW,GAAG,CAAC;AACvD,UAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,YAAQ,MAAM,cAAAA,QAAM,IAAI,YAAY,CAAC;AACrC,YAAQ,IAAI;AAAA,EAAK,cAAAA,QAAM,KAAK,QAAQ,CAAC,EAAE;AACvC,QAAI,cAAc,KAAK;AACnB,cAAQ,IAAI,cAAAA,QAAM,KAAK,QAAQ,WAAW,EAAE,CAAC;AAAA,IACjD;AACA,YAAQ,IAAI,cAAAA,QAAM,KAAK,qBAAqB,CAAC;AAAA,EACjD;AACJ;;;AM5RA,IAAAE,kBAAoB;AACpB,IAAAC,cAAgB;AAChB,IAAAC,eAAiB;AACjB,IAAAC,mBAAe;AACf,IAAAC,sBAA4B;;;ACF5B,IAAAC,mBAAe;AACf,IAAAC,eAAiB;AACjB,IAAAC,gBAAkB;AAGlB,IAAM,mBAA2C;AAAA,EAC7C,MAAM;AAAA,EACN,eAAe;AAAA,EACf,kBAAkB;AAAA,EAClB,WAAW;AAAA,EACX,iBAAiB;AAAA,EACjB,QAAQ;AAAA,EACR,MAAM;AACV;AAMO,IAAM,sBAAsB,OAC/B,oBACA,QACC;AACD,MAAI,CAAC,sBAAsB,mBAAmB,WAAW,GAAG;AACxD;AAAA,EACJ;AAEA,QAAM,SAAS,MAAM,eAAe,GAAG;AACvC,QAAM,SAAS,QAAQ,UAAU;AAEjC,aAAW,OAAO,oBAAoB;AAClC,QAAI,QAAQ,YAAY;AACpB,YAAM,WAAW,iBAAAC,QAAG,WAAW,aAAAC,QAAK,KAAK,KAAK,QAAQ,iBAAiB,aAAa,CAAC,CAAC;AACtF,YAAM,cAAc,iBAAAD,QAAG,WAAW,aAAAC,QAAK,KAAK,KAAK,QAAQ,iBAAiB,gBAAgB,CAAC,CAAC;AAE5F,UAAI,YAAY,aAAa;AACzB;AAAA,MACJ;AAEA,cAAQ,IAAI,cAAAC,QAAM,KAAK,sBAAiB,GAAG,qCAAqC,CAAC;AACjF,YAAM,IAAI,UAAU;AACpB;AAAA,IACJ;AAEA,UAAM,YAAY,iBAAiB,GAAG;AACtC,QAAI,CAAC,WAAW;AACZ;AAAA,IACJ;AAEA,QAAI,iBAAAF,QAAG,WAAW,aAAAC,QAAK,KAAK,KAAK,QAAQ,SAAS,CAAC,GAAG;AAClD;AAAA,IACJ;AAEA,YAAQ,IAAI,cAAAC,QAAM,KAAK,yCAAoC,GAAG,KAAK,CAAC;AACpE,UAAM,IAAI,GAAG;AAAA,EACjB;AACJ;;;ADjDA,IAAAC,gBAAkB;AAYlB,IAAM,wBAA4D;AAAA,EAC9D,eAAe;AAAA,EACf,kBAAkB;AACtB;AAEA,SAASC,uBAAsB,aAAqB,QAAgB,MAAoB;AACpF,QAAM,aAAa,aAAAC,QAAK,QAAQ,aAAa,QAAQ,KAAK,MAAM;AAChE,QAAM,iBAAiB,aAAAA,QAAK,QAAQ,WAAW;AAE/C,MAAI,eAAe,kBAAkB,CAAC,WAAW,WAAW,GAAG,cAAc,GAAG,aAAAA,QAAK,GAAG,EAAE,GAAG;AACzF,UAAM,IAAI,MAAM,gDAAgD,KAAK,MAAM,EAAE;AAAA,EACjF;AAEA,SAAO;AACX;AAEA,SAAS,sBAAsB,aAAqB;AAChD,MAAI,iBAAAC,QAAG,WAAW,aAAAD,QAAK,KAAK,aAAa,gBAAgB,CAAC,GAAG;AACzD,WAAO;AAAA,EACX;AAEA,MAAI,iBAAAC,QAAG,WAAW,aAAAD,QAAK,KAAK,aAAa,WAAW,CAAC,KAAK,iBAAAC,QAAG,WAAW,aAAAD,QAAK,KAAK,aAAa,UAAU,CAAC,GAAG;AACzG,WAAO;AAAA,EACX;AAEA,MAAI,iBAAAC,QAAG,WAAW,aAAAD,QAAK,KAAK,aAAa,WAAW,CAAC,GAAG;AACpD,WAAO;AAAA,EACX;AAEA,SAAO;AACX;AAEA,SAAS,qBAAqB,OAA2C;AACrE,QAAM,aAAa,OAAO,KAAK,EAAE,YAAY;AAC7C,MAAI,CAAC,YAAY;AACb,WAAO;AAAA,EACX;AAEA,MAAI,eAAe,QAAQ,eAAe,cAAc,eAAe,gBAAgB,eAAe,eAAe;AACjH,WAAO;AAAA,EACX;AAEA,MAAI,eAAe,WAAW,eAAe,kBAAkB;AAC3D,WAAO;AAAA,EACX;AAEA,SAAO;AACX;AAEA,SAAS,iBAAiB,YAAsD;AAC5E,SAAO,eAAe,iBAAiB,eAAe;AAC1D;AAEA,SAAS,oBAAoB,QAAgB,YAAgC;AACzE,QAAM,QAAQ,OAAO,KAAK;AAC1B,MAAI,CAAC,OAAO;AACR,UAAM,IAAI,MAAM,+BAA+B;AAAA,EACnD;AAEA,MAAI;AACJ,MAAI;AACA,aAAS,IAAI,IAAI,KAAK;AAAA,EAC1B,QAAQ;AACJ,UAAM,IAAI,MAAM,0BAA0B,KAAK,IAAI;AAAA,EACvD;AAEA,QAAM,WAAW,OAAO,SAAS,YAAY;AAC7C,MAAI,eAAe,iBAAiB,aAAa,iBAAiB,aAAa,aAAa;AACxF,UAAM,IAAI,MAAM,6DAA6D;AAAA,EACjF;AAEA,MAAI,eAAe,oBAAoB,aAAa,UAAU;AAC1D,UAAM,IAAI,MAAM,oCAAoC;AAAA,EACxD;AAEA,SAAO;AACX;AAEA,eAAe,+BAA+B,aAAqB,QAAoD;AACnH,QAAM,cAAc,aAAAA,QAAK,KAAK,aAAa,QAAQ,MAAM,UAAU;AACnE,MAAI,CAAC,iBAAAC,QAAG,WAAW,WAAW,GAAG;AAC7B,WAAO;AAAA,EACX;AAEA,QAAM,UAAU,MAAM,iBAAAA,QAAG,SAAS,aAAa,OAAO;AACtD,MAAI,QAAQ,SAAS,2BAA2B,KAAK,QAAQ,SAAS,WAAW,GAAG;AAChF,WAAO;AAAA,EACX;AAEA,MAAI,QAAQ,SAAS,oBAAoB,KAAK,QAAQ,SAAS,cAAc,GAAG;AAC5E,WAAO;AAAA,EACX;AAEA,SAAO;AACX;AAEA,eAAe,oBAAoB,aAAqB,QAAwC;AAC5F,QAAM,aAAY,oBAAI,KAAK,GAAE,YAAY,EAAE,QAAQ,SAAS,GAAG;AAC/D,QAAM,aAAa,aAAAD,QAAK,KAAK,aAAa,SAAS,WAAW,YAAY,SAAS,EAAE;AACrF,QAAM,aAAa;AAAA,IACf,aAAAA,QAAK,KAAK,aAAa,QAAQ,MAAM,UAAU;AAAA,IAC/C,aAAAA,QAAK,KAAK,aAAa,mBAAmB;AAAA,EAC9C;AAEA,MAAI,SAAS;AACb,aAAW,YAAY,YAAY;AAC/B,QAAI,CAAC,iBAAAC,QAAG,WAAW,QAAQ,GAAG;AAC1B;AAAA,IACJ;AAEA,UAAM,eAAe,aAAAD,QAAK,SAAS,aAAa,QAAQ;AACxD,UAAM,aAAa,aAAAA,QAAK,KAAK,YAAY,YAAY;AACrD,UAAM,iBAAAC,QAAG,UAAU,aAAAD,QAAK,QAAQ,UAAU,CAAC;AAC3C,UAAM,iBAAAC,QAAG,SAAS,UAAU,UAAU;AACtC,aAAS;AAAA,EACb;AAEA,SAAO,SAAS,aAAa;AACjC;AAEA,SAAS,cAAc,YAAgC;AACnD,SAAO,eAAe,gBAAgB,eAAe;AACzD;AAEA,SAAS,qBAAqB,YAAgC,OAAe;AACzE,MAAI;AACA,UAAM,SAAS,IAAI,IAAI,KAAK;AAC5B,UAAM,SAAS,OAAO,SAAS,QAAQ,QAAQ,EAAE,KAAK;AAEtD,QAAI,eAAe,eAAe;AAC9B,aAAO,YAAY,MAAM;AAAA,IAC7B;AAEA,WAAO,2CAA2C,MAAM;AAAA,EAC5D,QAAQ;AACJ,WAAO,eAAe,gBAChB,6BACA;AAAA,EACV;AACJ;AAEA,SAAS,kBAAkB,YAAoB;AAC3C,MAAI,iBAAiB,UAAU,GAAG;AAC9B,WAAO;AAAA,EACX;AAEA,SAAO;AACX;AAEA,SAAS,YAAY,OAAe;AAChC,SAAO,MAAM,QAAQ,uBAAuB,MAAM;AACtD;AAEA,eAAe,eAAe,aAAqB,KAA+B;AAC9E,QAAM,UAAU,aAAAD,QAAK,KAAK,aAAa,MAAM;AAC7C,MAAI,CAAC,MAAM,iBAAAC,QAAG,WAAW,OAAO,GAAG;AAC/B,WAAO;AAAA,EACX;AAEA,QAAM,UAAU,MAAM,iBAAAA,QAAG,SAAS,SAAS,OAAO;AAClD,QAAM,UAAU,IAAI,OAAO,IAAI,YAAY,GAAG,CAAC,KAAK,GAAG;AACvD,SAAO,QAAQ,KAAK,OAAO;AAC/B;AAEA,eAAe,uBAAuB,KAA+B;AACjE,QAAM,UAAU,MAAM,iBAAAA,QAAG,QAAQ,GAAG;AACpC,QAAM,UAAU,oBAAI,IAAI,CAAC,aAAa,WAAW,CAAC;AAElD,SAAO,QAAQ,OAAO,CAAC,UAAU,CAAC,QAAQ,IAAI,MAAM,YAAY,CAAC,CAAC,EAAE,WAAW;AACnF;AAEA,eAAe,mBAAmB,aAAqB,QAAgB,gBAAwB;AAC3F,QAAM,kBAAkB,aAAAD,QAAK,KAAK,aAAa,QAAQ,MAAM,UAAU,UAAU;AACjF,MAAI,CAAC,MAAM,iBAAAC,QAAG,WAAW,eAAe,GAAG;AACvC;AAAA,EACJ;AAEA,QAAM,aAAa,oBAAoB,cAAc;AACrD,QAAM,UAAU,MAAM,iBAAAA,QAAG,SAAS,iBAAiB,OAAO;AAC1D,QAAM,aAAa,QAAQ,QAAQ,SAAS,IAAI;AAChD,QAAM,gBAAgB,IAAI;AAAA,IACtB,yCAAyC,YAAY,cAAc,CAAC;AAAA,IACpE;AAAA,EACJ;AAEA,MAAI,cAAc,KAAK,UAAU,GAAG;AAChC;AAAA,EACJ;AAEA,MAAI,OAAO,WACN,QAAQ,+BAA+B,EAAE,EACzC,QAAQ;AAEb,MAAI,KAAK,SAAS,GAAG;AACjB,YAAQ;AAAA,EACZ;AAEA,UAAQ,GAAG,UAAU;AAAA;AACrB,QAAM,iBAAAA,QAAG,UAAU,iBAAiB,IAAI;AAC5C;AAKA,eAAe,mBAAmB,aAAqB,QAAkC;AACrF,QAAM,UAAU,aAAAD,QAAK,KAAK,aAAa,QAAQ,QAAQ;AAEvD,MAAI,CAAC,iBAAAC,QAAG,WAAW,OAAO,GAAG;AACzB,WAAO;AAAA,EACX;AAEA,MAAI,UAAU,MAAM,iBAAAA,QAAG,SAAS,SAAS,OAAO;AAEhD,QAAM,cAAc;AACpB,QAAM,iBAAiB,QAAQ,SAAS,WAAW;AACnD,QAAM,iBAAiB,oCAAoC,KAAK,OAAO;AACvE,QAAM,cAAc,iCAAiC,KAAK,OAAO;AACjE,MAAI,WAAW;AACf,MAAI,iBAAiB;AAErB,MAAI,CAAC,gBAAgB;AACjB,UAAM,cAAc;AACpB,QAAI,kBAAkB;AACtB,QAAI;AAEJ,YAAQ,QAAQ,YAAY,KAAK,OAAO,OAAO,MAAM;AACjD,wBAAkB,MAAM,QAAQ,MAAM,CAAC,EAAE;AAAA,IAC7C;AAEA,QAAI,kBAAkB,GAAG;AACrB,gBAAU,QAAQ,MAAM,GAAG,eAAe,IAAI;AAAA,EAAK,WAAW,KAAK,QAAQ,MAAM,eAAe;AAChG,iBAAW;AACX,uBAAiB;AAAA,IACrB;AAAA,EACJ;AAEA,MAAI,gBAAgB,kBAAkB;AACtC,MAAI,CAAC,eAAe;AAChB,UAAM,aAAuB,CAAC;AAC9B,QAAI,CAAC,gBAAgB;AACjB,iBAAW,KAAK,2BAA2B;AAAA,IAC/C;AAEA,QAAI,CAAC,aAAa;AACd,iBAAW,KAAK,wBAAwB;AAAA,IAC5C;AAEA,UAAM,aAAa;AAAA;AAAA,EAAuC,WAAW,KAAK,IAAI,CAAC;AAAA;AAC/E,UAAM,cAAc,QAAQ,MAAM,2BAA2B;AAC7D,QAAI,eAAe,YAAY,UAAU,QAAW;AAChD,gBAAU,QAAQ,MAAM,GAAG,YAAY,KAAK,IAAI,aAAa,OAAO,QAAQ,MAAM,YAAY,KAAK;AACnG,iBAAW;AACX,sBAAgB;AAAA,IACpB;AAAA,EACJ;AAEA,MAAI,UAAU;AACV,UAAM,iBAAAA,QAAG,UAAU,SAAS,OAAO;AAAA,EACvC;AAEA,SAAO,kBAAkB;AAC7B;AAKA,eAAe,iBAAiB,aAAqB,QAAkC;AACnF,QAAM,UAAU,aAAAD,QAAK,KAAK,aAAa,QAAQ,QAAQ;AACvD,MAAI,CAAC,MAAM,iBAAAC,QAAG,WAAW,OAAO,GAAG;AAC/B,WAAO;AAAA,EACX;AAEA,MAAI,aAAa,MAAM,iBAAAA,QAAG,SAAS,SAAS,OAAO;AACnD,QAAM,oBAAoB;AAC1B,QAAM,aAAa;AACnB,QAAM,aAAa;AAEnB,MAAI,cAAc;AAElB,QAAM,eAAe,CAAC,QAAgB,SAAiB;AACnD,QAAI,OAAO,SAAS,IAAI,GAAG;AACvB,aAAO,EAAE,QAAQ,UAAU,KAAK;AAAA,IACpC;AAEA,UAAM,cAAc;AACpB,QAAI,kBAAkB;AACtB,QAAI;AACJ,YAAQ,QAAQ,YAAY,KAAK,MAAM,OAAO,MAAM;AAChD,wBAAkB,MAAM,QAAQ,MAAM,CAAC,EAAE;AAAA,IAC7C;AAEA,QAAI,mBAAmB,GAAG;AACtB,aAAO,EAAE,QAAQ,UAAU,MAAM;AAAA,IACrC;AAEA,WAAO;AAAA,MACH,QAAQ,OAAO,MAAM,GAAG,eAAe,IAAI;AAAA,EAAK,IAAI,KAAK,OAAO,MAAM,eAAe;AAAA,MACrF,UAAU;AAAA,IACd;AAAA,EACJ;AAEA,aAAW,cAAc,CAAC,mBAAmB,UAAU,GAAG;AACtD,UAAM,OAAO,aAAa,YAAY,UAAU;AAChD,QAAI,CAAC,KAAK,UAAU;AAChB,aAAO;AAAA,IACX;AAEA,QAAI,KAAK,WAAW,YAAY;AAC5B,mBAAa,KAAK;AAClB,oBAAc;AAAA,IAClB;AAAA,EACJ;AAEA,QAAM,eAAe,8BAA8B,KAAK,UAAU,KAC3D,cAAc,KAAK,UAAU;AACpC,MAAI,CAAC,cAAc;AACf,UAAM,gBAAgB;AACtB,UAAM,YAAY,WAAW,OAAO,+CAA+C;AAEnF,QAAI,iBAAiB;AACrB,QAAI,iBAAiB,GAAG;AACpB,YAAM,cAAc,WAAW,OAAO,wCAAwC;AAC9E,uBAAiB;AAAA,IACrB;AAEA,QAAI,iBAAiB,GAAG;AACpB,YAAM,cAAc,WAAW,MAAM,2BAA2B;AAChE,uBAAiB,aAAa,SAAS;AAAA,IAC3C;AAEA,QAAI,iBAAiB,GAAG;AACpB,aAAO;AAAA,IACX;AAEA,iBAAa,WAAW,MAAM,GAAG,cAAc,IAAI,gBAAgB,WAAW,MAAM,cAAc;AAClG,kBAAc;AAAA,EAClB;AAEA,QAAM,iBAAiB,aAAAD,QAAK,KAAK,aAAa,QAAQ,UAAU,UAAU;AAC1E,MAAI,MAAM,iBAAAC,QAAG,WAAW,cAAc,GAAG;AACrC,QAAI,eAAe,MAAM,iBAAAA,QAAG,SAAS,gBAAgB,OAAO;AAC5D,QAAI,gBAAgB;AAEpB,UAAM,mBAAmB,aAAa,cAAc,UAAU;AAC9D,QAAI,CAAC,iBAAiB,UAAU;AAC5B,aAAO;AAAA,IACX;AAEA,QAAI,iBAAiB,WAAW,cAAc;AAC1C,qBAAe,iBAAiB;AAChC,sBAAgB;AAAA,IACpB;AAEA,UAAM,eAAe,4DAA4D,KAAK,YAAY;AAClG,QAAI,CAAC,cAAc;AACf,YAAM,aAAa;AAAA;AAAA;AAAA;AACnB,YAAM,cAAc,aAAa,MAAM,kCAAkC;AAEzE,UAAI,CAAC,eAAe,YAAY,UAAU,QAAW;AACjD,eAAO;AAAA,MACX;AAEA,qBAAe,aAAa,MAAM,GAAG,YAAY,KAAK,IAAI,aAAa,OAAO,aAAa,MAAM,YAAY,KAAK;AAClH,sBAAgB;AAAA,IACpB;AAEA,QAAI,eAAe;AACf,YAAM,iBAAAA,QAAG,UAAU,gBAAgB,YAAY;AAAA,IACnD;AAAA,EACJ,OAAO;AACH,UAAM,eAAe,0DAA0D,KAAK,UAAU;AAC9F,QAAI,CAAC,cAAc;AACf,YAAM,cAAc,WAAW,MAAM,2BAA2B;AAChE,UAAI,CAAC,eAAe,YAAY,UAAU,QAAW;AACjD,eAAO;AAAA,MACX;AAEA,YAAM,aAAa;AAAA;AAAA;AAAA;AACnB,mBAAa,WAAW,MAAM,GAAG,YAAY,KAAK,IAAI,aAAa,OAAO,WAAW,MAAM,YAAY,KAAK;AAC5G,oBAAc;AAAA,IAClB;AAEA,UAAM,mBAAmB,aAAa,YAAY,UAAU;AAC5D,QAAI,CAAC,iBAAiB,UAAU;AAC5B,aAAO;AAAA,IACX;AAEA,QAAI,iBAAiB,WAAW,YAAY;AACxC,mBAAa,iBAAiB;AAC9B,oBAAc;AAAA,IAClB;AAAA,EACJ;AAEA,MAAI,aAAa;AACb,UAAM,iBAAAA,QAAG,UAAU,SAAS,UAAU;AAAA,EAC1C;AAEA,SAAO;AACX;AAEO,IAAM,MAAM,OAAO,eAAuB;AAC7C,QAAM,cAAc,QAAQ,IAAI;AAChC,QAAM,gBAAgB,MAAM,eAAe,WAAW;AACtD,MAAI,CAAC,eAAe;AAChB,QAAI,MAAM,uBAAuB,WAAW,GAAG;AAC3C,2BAAqB;AACrB;AAAA,IACJ;AAEA,8BAA0B;AAC1B;AAAA,EACJ;AACA,QAAM,SAAS,cAAc,UAAU;AACvC,MAAI,qBAAqB;AACzB,QAAM,gBAAgB,qBAAqB,UAAU;AACrD,MAAI,eAAe;AACf,yBAAqB;AAAA,EACzB;AAEA,MAAI;AACJ,MAAI,mBAAmB;AACvB,MAAI,qBAAoC;AACxC,MAAI,sBAAsB;AAC1B,MAAI,sBAAiD;AAErD,MAAI,uBAAuB,YAAY;AACnC,UAAM,kBAAkB,UAAM,gBAAAC,SAAQ;AAAA,MAClC,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,QACL,EAAE,OAAO,cAAc,OAAO,cAAc;AAAA,QAC5C,EAAE,OAAO,SAAS,OAAO,iBAAiB;AAAA,MAC9C;AAAA,IACJ,CAAC;AAED,QAAI,CAAC,gBAAgB,SAAS;AAC1B,cAAQ,IAAI,cAAAC,QAAM,OAAO,sBAAsB,CAAC;AAChD;AAAA,IACJ;AAEA,yBAAqB,gBAAgB;AAAA,EACzC;AAEA,MAAI,iBAAiB,kBAAkB,GAAG;AACtC,UAAM,mBAAmB,MAAM,+BAA+B,aAAa,MAAM;AAEjF,QAAI,oBAAoB,qBAAqB,oBAAoB;AAC7D,cAAQ;AAAA,QACJ,cAAAA,QAAM;AAAA,UACF;AAAA,2CAAyC,cAAc,gBAAgB,CAAC;AAAA,QAC5E;AAAA,MACJ;AACA,cAAQ;AAAA,QACJ,cAAAA,QAAM;AAAA,UACF,kBAAkB,cAAc,kBAAkB,CAAC;AAAA;AAAA,QACvD;AAAA,MACJ;AAEA,YAAM,iBAAiB,UAAM,gBAAAD,SAAQ;AAAA,QACjC,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,MACb,CAAC;AAED,UAAI,CAAC,eAAe,SAAS;AACzB,gBAAQ,IAAI,cAAAC,QAAM,OAAO,sBAAsB,CAAC;AAChD;AAAA,MACJ;AAEA,2BAAqB,MAAM,oBAAoB,aAAa,MAAM;AAAA,IACtE;AAEA,UAAM,aAAa,sBAAsB,kBAAkB;AAC3D,YAAQ,IAAI,cAAAA,QAAM,IAAI,6BAA6B,UAAU;AAAA,CAAI,CAAC;AAElE,UAAM,WAAW,UAAM,gBAAAD,SAAQ;AAAA,MAC3B,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,IACb,CAAC;AAED,QAAI,SAAS,UAAU,QAAW;AAC9B,cAAQ,IAAI,cAAAC,QAAM,OAAO,sBAAsB,CAAC;AAChD;AAAA,IACJ;AAEA,UAAM,aAAa,SAAS,OAAO,KAAK,KAAK;AAC7C,uBAAmB,WAAW,WAAW;AACzC,kBAAc,oBAAoB,cAAc,YAAY,kBAAkB;AAAA,EAClF;AAEA,QAAM,KAAK,sBAAsB,WAAW;AAC5C,QAAM,cAAU,YAAAC,SAAI,yBAAyB,kBAAkB,KAAK,EAAE,MAAM;AAC5E,MAAI,cAAc;AAElB,MAAI;AACA,YAAQ,OAAO,YAAY,EAAE;AAC7B,UAAM,8BAA8B,EAAE;AAEtC,kBAAc;AACd,YAAQ,OAAO,yBAAyB,kBAAkB;AAC1D,UAAM,kBAAkB,MAAM,cAAc;AAC5C,UAAMC,UAAS,gBAAgB,SAAS,QAAQ,kBAAkB;AAElE,QAAI,CAACA,SAAQ;AACT,cAAQ,KAAK,WAAW,kBAAkB,cAAc;AACxD;AAAA,IACJ;AAEA,YAAQ,QAAQ,iBAAiB,cAAAF,QAAM,KAAK,kBAAkB,CAAC,EAAE;AAEjE,UAAM,aAAaE,QAAO,sBAAsB,CAAC;AACjD,kBAAc;AACd,UAAM,oBAAoB,YAAY,WAAW;AAEjD,kBAAc;AACd,YAAQ,MAAM,4BAA4B;AAE1C,UAAM,oBAAoB,IAAIA,QAAO,gBAAgB,CAAC,GAAG,WAAW;AACpE,UAAM,oBAAoB,IAAIA,QAAO,mBAAmB,CAAC,GAAG,aAAa,EAAE,KAAK,KAAK,CAAC;AAEtF,YAAQ,QAAQ,wBAAwB;AAExC,kBAAc;AACd,YAAQ,MAAM,sBAAsB;AAEpC,QAAI,uBAAuB,QAAQ;AAC/B,4BAAsB,MAAM,+BAA+B,aAAa,MAAM;AAAA,IAClF;AAEA,eAAW,QAAQA,QAAO,OAAO;AAC7B,UAAI,YAAY,KAAK;AACrB,UAAI,iBAAiB,KAAK;AAC1B,UAAI,eAAe,KAAK;AAExB,UACI,uBAAuB,UACpB,KAAK,WAAW,uBAChB,wBAAwB,kBAC7B;AACE,oBAAY;AACZ,yBAAiB;AACjB,uBAAe;AAAA,MACnB;AAEA,UAAI,UAAU,MAAM,UAAU,WAAW;AAAA,QACrC,SAAS,gBAAgB;AAAA,QACzB;AAAA,QACA;AAAA,MACJ,CAAC;AAED,UAAI,iBAAiB,kBAAkB,KAAK,KAAK,WAAW,wBAAwB;AAChF,cAAM,mBAAmB,OAAO,QAAQ,OAAO,GAAG;AAClD,kBAAU,QAAQ;AAAA,UACd;AAAA,UACA,cAAc,gBAAgB;AAAA,QAClC;AAAA,MACJ;AAEA,YAAM,aAAaN,uBAAsB,aAAa,QAAQ,IAAI;AAElE,YAAM,iBAAAE,QAAG,UAAU,aAAAD,QAAK,QAAQ,UAAU,CAAC;AAC3C,YAAM,iBAAAC,QAAG,UAAU,YAAY,OAAO;AAAA,IAC1C;AAEA,UAAM,gBAAgBI,QAAO,MACxB,IAAI,CAAC,SAAS,KAAK,OAAO,QAAQ,OAAO,GAAG,CAAC,EAC7C,OAAO,CAAC,WAAW,0BAA0B,KAAK,MAAM,CAAC,EACzD,IAAI,CAAC,WAAW,aAAAL,QAAK,MAAM,SAAS,QAAQ,KAAK,CAAC,EAClD,OAAO,CAAC,SAAS,SAAS,OAAO;AAEtC,eAAW,kBAAkB,eAAe;AACxC,YAAM,mBAAmB,aAAa,QAAQ,cAAc;AAAA,IAChE;AAEA,YAAQ,QAAQ,iBAAiB;AAEjC,QAAI,uBAAuB,QAAQ;AAC/B,cAAQ,MAAM,uBAAuB;AACrC,YAAM,WAAW,MAAM,iBAAiB,aAAa,MAAM;AAC3D,UAAI,UAAU;AACV,gBAAQ,QAAQ,mBAAmB;AAAA,MACvC,OAAO;AACH,gBAAQ,KAAK,0CAA0C;AAAA,MAC3D;AAAA,IACJ;AAEA,QAAI,uBAAuB,iBAAiB;AACxC,cAAQ,MAAM,wCAAwC;AACtD,YAAM,WAAW,MAAM,mBAAmB,aAAa,MAAM;AAC7D,UAAI,UAAU;AACV,gBAAQ,QAAQ,oCAAoC;AAAA,MACxD,OAAO;AACH,gBAAQ,KAAK,0DAA0D;AAAA,MAC3E;AAAA,IACJ;AAEA,UAAM,YAAY,YAAY,kBAA8C;AAC5E,QAAI,WAAW;AACX,oBAAc;AACd,cAAQ,MAAM,uCAAuC;AAErD,YAAM,UAAkC,EAAE,GAAG,UAAU,QAAQ;AAC/D,UAAI,eAAe,iBAAiB,kBAAkB,GAAG;AACrD,gBAAQ,eAAe;AAAA,MAC3B;AAEA,UAAI,uBAAuB,QAAQ;AAC/B,cAAM,oBAAoB,MAAM,eAAe,aAAa,oBAAoB;AAChF,YAAI,CAAC,mBAAmB;AACpB,kBAAQ,yBAAqB,iCAAY,EAAE,EAAE,SAAS,KAAK;AAC3D,gCAAsB;AAAA,QAC1B;AAAA,MACJ;AAEA,YAAM,cAAc,aAAa,SAAS,MAAM;AAAA,QAC5C,mBAAmB,iBAAiB,kBAAkB;AAAA,MAC1D,CAAC;AACD,YAAM,gBAAgB,aAAa,QAAQ,UAAU,YAAY;AAEjE,cAAQ,QAAQ,wBAAwB;AAAA,IAC5C;AAEA,YAAQ,IAAI,cAAAG,QAAM,MAAM;AAAA,SAAO,kBAAkB;AAAA,CAAwB,CAAC;AAE1E,QAAI,oBAAoB;AACpB,cAAQ,IAAI,cAAAA,QAAM,KAAK,6BAAwB,kBAAkB;AAAA,CAAI,CAAC;AAAA,IAC1E;AAEA,UAAM,WAAW,kBAAkB,kBAAkB;AACrD,UAAM,UAAU,yCAAyC,QAAQ;AACjE,YAAQ,IAAI,cAAAA,QAAM,KAAK,gBAAW,OAAO,EAAE,CAAC;AAE5C,QAAI,iBAAiB,kBAAkB,GAAG;AACtC,UAAI,kBAAkB;AAClB,gBAAQ,IAAI,cAAAA,QAAM,OAAO,qEAAgE,CAAC;AAAA,MAC9F;AAEA,YAAM,YAAY;AAAA,QACd;AAAA,QACA,eAAe,sBAAsB,kBAAkB;AAAA,MAC3D;AACA,cAAQ,IAAI,cAAAA,QAAM,OAAO,4BAAuB,SAAS,EAAE,CAAC;AAC5D,cAAQ,IAAI,cAAAA,QAAM,OAAO,4EAAuE,CAAC;AAAA,IACrG;AAEA,QAAI,uBAAuB,QAAQ;AAC/B,UAAI,qBAAqB;AACrB,gBAAQ,IAAI,cAAAA,QAAM,OAAO,wDAAmD,CAAC;AAAA,MACjF,OAAO;AACH,gBAAQ,IAAI,cAAAA,QAAM,OAAO,+DAA0D,CAAC;AAAA,MACxF;AAEA,cAAQ,IAAI,cAAAA,QAAM,OAAO,4EAAuE,CAAC;AAAA,IACrG;AAAA,EACJ,SAAS,OAAO;AACZ,YAAQ,KAAK,cAAAA,QAAM,IAAI,iBAAiB,WAAW,GAAG,CAAC;AACvD,UAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;AAC1E,YAAQ,MAAM,cAAAA,QAAM,IAAI,YAAY,CAAC;AACrC,YAAQ,IAAI;AAAA,EAAK,cAAAA,QAAM,KAAK,QAAQ,CAAC,EAAE;AACvC,YAAQ,IAAI,cAAAA,QAAM,KAAK,sBAAsB,kBAAkB,EAAE,CAAC;AAAA,EACtE;AACJ;;;APzqBA,IAAM,UAAU,IAAI,yBAAQ;AAE5B,QACK,KAAK,UAAU,EACf,YAAY,eAAe,EAC3B,QAAQ,OAAO;AAEpB,QACK,QAAQ,MAAM,EACd,YAAY,+BAA+B,EAC3C,OAAO,IAAI;AAEhB,QACK,QAAQ,cAAc,EACtB,YAAY,8BAA8B,EAC1C,OAAO,GAAG;AAEf,QAAQ,MAAM,QAAQ,IAAI;","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_node_crypto","import_fs_extra","import_path","import_chalk","fs","path","chalk","import_chalk","resolveSafeTargetPath","path","fs","prompts","chalk","ora","module"]}
package/dist/index.mjs CHANGED
@@ -881,69 +881,117 @@ ${setupLines.join("\n")}
881
881
  }
882
882
  async function injectAuthRoutes(projectRoot, srcDir) {
883
883
  const appPath = path6.join(projectRoot, srcDir, "app.ts");
884
- if (!fs6.existsSync(appPath)) {
884
+ if (!await fs6.pathExists(appPath)) {
885
885
  return false;
886
886
  }
887
- let content = await fs6.readFile(appPath, "utf-8");
888
- const authImport = `import authRoutes from "./routes/auth.routes";`;
887
+ let appContent = await fs6.readFile(appPath, "utf-8");
888
+ const authHandlerImport = `import { toNodeHandler } from "better-auth/node";`;
889
+ const authImport = `import { auth } from "./lib/auth";`;
889
890
  const userImport = `import userRoutes from "./routes/user.routes";`;
890
- const hasAuthImport = content.includes(authImport);
891
- const hasUserImport = content.includes(userImport);
892
- const hasAuthRoute = /app\.use\(\s*authRoutes\s*\)/.test(content);
893
- const hasUserRoute = /app\.use\(\s*["']\/api\/users["']\s*,\s*userRoutes\s*\)/.test(content);
894
- let modified = false;
895
- let importsReady = hasAuthImport && hasUserImport;
896
- if (!importsReady) {
891
+ let appModified = false;
892
+ const appendImport = (source, line) => {
893
+ if (source.includes(line)) {
894
+ return { source, inserted: true };
895
+ }
897
896
  const importRegex = /^import .+ from .+;?\s*$/gm;
898
897
  let lastImportIndex = 0;
899
898
  let match;
900
- while ((match = importRegex.exec(content)) !== null) {
899
+ while ((match = importRegex.exec(source)) !== null) {
901
900
  lastImportIndex = match.index + match[0].length;
902
901
  }
903
- if (lastImportIndex > 0) {
904
- const missingImports = [];
905
- if (!hasAuthImport) {
906
- missingImports.push(authImport);
907
- }
908
- if (!hasUserImport) {
909
- missingImports.push(userImport);
910
- }
911
- content = content.slice(0, lastImportIndex) + `
912
- ${missingImports.join("\n")}` + content.slice(lastImportIndex);
913
- modified = true;
914
- importsReady = true;
902
+ if (lastImportIndex <= 0) {
903
+ return { source, inserted: false };
904
+ }
905
+ return {
906
+ source: source.slice(0, lastImportIndex) + `
907
+ ${line}` + source.slice(lastImportIndex),
908
+ inserted: true
909
+ };
910
+ };
911
+ for (const importLine of [authHandlerImport, authImport]) {
912
+ const next = appendImport(appContent, importLine);
913
+ if (!next.inserted) {
914
+ return false;
915
+ }
916
+ if (next.source !== appContent) {
917
+ appContent = next.source;
918
+ appModified = true;
915
919
  }
916
920
  }
917
- let setupReady = hasAuthRoute && hasUserRoute;
918
- if (!setupReady) {
919
- const setupLines = [];
920
- if (!hasAuthRoute) {
921
- setupLines.push("app.use(authRoutes);");
921
+ const hasAuthMount = /toNodeHandler\(\s*auth\s*\)/.test(appContent) && /\/api\/auth/.test(appContent);
922
+ if (!hasAuthMount) {
923
+ const authMountLine = "app.all(/^\\/api\\/auth(?:\\/.*)?$/, toNodeHandler(auth));\n";
924
+ const jsonIndex = appContent.search(/^\s*app\.use\(\s*express\.json\(\)\s*\);\s*$/m);
925
+ let insertionIndex = jsonIndex;
926
+ if (insertionIndex < 0) {
927
+ const healthIndex = appContent.search(/^\s*app\.get\(\s*["']\/health["']\s*,/m);
928
+ insertionIndex = healthIndex;
922
929
  }
930
+ if (insertionIndex < 0) {
931
+ const exportMatch = appContent.match(/export default app;?\s*$/m);
932
+ insertionIndex = exportMatch?.index ?? -1;
933
+ }
934
+ if (insertionIndex < 0) {
935
+ return false;
936
+ }
937
+ appContent = appContent.slice(0, insertionIndex) + authMountLine + appContent.slice(insertionIndex);
938
+ appModified = true;
939
+ }
940
+ const routeIndexPath = path6.join(projectRoot, srcDir, "routes", "index.ts");
941
+ if (await fs6.pathExists(routeIndexPath)) {
942
+ let routeContent = await fs6.readFile(routeIndexPath, "utf-8");
943
+ let routeModified = false;
944
+ const userImportResult = appendImport(routeContent, userImport);
945
+ if (!userImportResult.inserted) {
946
+ return false;
947
+ }
948
+ if (userImportResult.source !== routeContent) {
949
+ routeContent = userImportResult.source;
950
+ routeModified = true;
951
+ }
952
+ const hasUserRoute = /rootRouter\.use\(\s*["']\/users["']\s*,\s*userRoutes\s*\)/.test(routeContent);
923
953
  if (!hasUserRoute) {
924
- setupLines.push('app.use("/api/users", userRoutes);');
954
+ const routeSetup = `
955
+ // User routes
956
+ rootRouter.use("/users", userRoutes);
957
+ `;
958
+ const exportMatch = routeContent.match(/export default rootRouter;?\s*$/m);
959
+ if (!exportMatch || exportMatch.index === void 0) {
960
+ return false;
961
+ }
962
+ routeContent = routeContent.slice(0, exportMatch.index) + routeSetup + "\n" + routeContent.slice(exportMatch.index);
963
+ routeModified = true;
925
964
  }
926
- const routeSetup = `
927
- // Auth routes
928
- ${setupLines.join("\n")}
965
+ if (routeModified) {
966
+ await fs6.writeFile(routeIndexPath, routeContent);
967
+ }
968
+ } else {
969
+ const hasUserRoute = /app\.use\(\s*["']\/api\/users["']\s*,\s*userRoutes\s*\)/.test(appContent);
970
+ if (!hasUserRoute) {
971
+ const exportMatch = appContent.match(/export default app;?\s*$/m);
972
+ if (!exportMatch || exportMatch.index === void 0) {
973
+ return false;
974
+ }
975
+ const routeSetup = `
976
+ // User routes
977
+ app.use("/api/users", userRoutes);
929
978
  `;
930
- const notFoundIndex = content.search(/^\s*app\.use\(\s*notFoundHandler\s*\);\s*$/m);
931
- const errorHandlerIndex = content.search(/^\s*app\.use\(\s*errorHandler\s*\);\s*$/m);
932
- const candidates = [notFoundIndex, errorHandlerIndex].filter((index) => index >= 0);
933
- const insertionIndex = candidates.length > 0 ? Math.min(...candidates) : (() => {
934
- const exportMatch = content.match(/export default app;?\s*$/m);
935
- return exportMatch?.index ?? -1;
936
- })();
937
- if (insertionIndex >= 0) {
938
- content = content.slice(0, insertionIndex) + routeSetup + "\n" + content.slice(insertionIndex);
939
- modified = true;
940
- setupReady = true;
979
+ appContent = appContent.slice(0, exportMatch.index) + routeSetup + "\n" + appContent.slice(exportMatch.index);
980
+ appModified = true;
981
+ }
982
+ const userImportResult = appendImport(appContent, userImport);
983
+ if (!userImportResult.inserted) {
984
+ return false;
985
+ }
986
+ if (userImportResult.source !== appContent) {
987
+ appContent = userImportResult.source;
988
+ appModified = true;
941
989
  }
942
990
  }
943
- if (modified) {
944
- await fs6.writeFile(appPath, content);
991
+ if (appModified) {
992
+ await fs6.writeFile(appPath, appContent);
945
993
  }
946
- return importsReady && setupReady;
994
+ return true;
947
995
  }
948
996
  var add = async (moduleName) => {
949
997
  const projectRoot = process.cwd();
@@ -1086,12 +1134,12 @@ var add = async (moduleName) => {
1086
1134
  }
1087
1135
  spinner.succeed("Files generated");
1088
1136
  if (resolvedModuleName === "auth") {
1089
- spinner.start("Configuring routes in app.ts...");
1137
+ spinner.start("Configuring routes...");
1090
1138
  const injected = await injectAuthRoutes(projectRoot, srcDir);
1091
1139
  if (injected) {
1092
- spinner.succeed("Routes configured in app.ts");
1140
+ spinner.succeed("Routes configured");
1093
1141
  } else {
1094
- spinner.warn("Could not find app.ts - routes need manual setup");
1142
+ spinner.warn("Could not configure routes automatically");
1095
1143
  }
1096
1144
  }
1097
1145
  if (resolvedModuleName === "error-handler") {
@@ -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, 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\nasync function setupPrettier(targetDir: string) {\n const prettierConfigPath = path.join(targetDir, \".prettierrc\");\n const prettierIgnorePath = path.join(targetDir, \".prettierignore\");\n\n if (!await fs.pathExists(prettierConfigPath)) {\n const prettierConfig = {\n semi: true,\n singleQuote: false,\n trailingComma: \"es5\",\n printWidth: 100,\n tabWidth: 2,\n };\n await fs.writeJson(prettierConfigPath, prettierConfig, { spaces: 2 });\n }\n\n if (!await fs.pathExists(prettierIgnorePath)) {\n const ignoreContent = `node_modules\ndist\nbuild\ncoverage\n.next\npnpm-lock.yaml\npackage-lock.json\nbun.lock\nbun.lockb\n`;\n await fs.writeFile(prettierIgnorePath, ignoreContent);\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 let enablePrettier = false;\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 type: \"confirm\",\n name: \"prettier\",\n message: \"Setup Prettier?\",\n initial: true,\n },\n ]);\n\n if (response.pm === undefined) {\n console.log(chalk.red(\"Operation cancelled.\"));\n return;\n }\n\n pm = response.pm;\n enablePrettier = response.prettier === true;\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, { enablePrettier });\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 if (enablePrettier) {\n await installDependencies(pm, [\"prettier\"], targetDir, { dev: true });\n }\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 if (enablePrettier) {\n currentStep = \"prettier setup\";\n await setupPrettier(targetDir);\n }\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 options: { enablePrettier?: boolean } = {}\n) {\n const pkgPath = path.join(cwd, \"package.json\");\n if (force || !await fs.pathExists(pkgPath)) {\n const scripts: Record<string, string> = {\n \"dev\": `tsx watch ${srcDir}/server.ts`,\n \"build\": \"tsc\",\n \"start\": \"node dist/server.js\"\n };\n\n if (options.enablePrettier) {\n scripts[\"format\"] = \"prettier --write .\";\n scripts[\"format:check\"] = \"prettier --check .\";\n }\n\n await fs.writeJson(pkgPath, {\n name: normalizePackageName(packageName),\n version: \"0.0.1\",\n private: true,\n scripts\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 (\n cwd: string,\n variables: Record<string, string>,\n createIfMissing = true,\n options: { overwriteExisting?: boolean } = {}\n) => {\n const envPath = path.join(cwd, \".env\");\n const overwriteExisting = options.overwriteExisting ?? false;\n\n let content = \"\";\n if (fs.existsSync(envPath)) {\n content = await fs.readFile(envPath, \"utf-8\");\n } else if (!createIfMissing) {\r\n return;\r\n }\r\n\r\n let modified = false;\n\n for (const [key, value] of Object.entries(variables)) {\n const escapedKey = key.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const regex = new RegExp(`^${escapedKey}=.*$`, \"m\");\n\n if (regex.test(content)) {\n if (!overwriteExisting) {\n continue;\n }\n\n const nextLine = `${key}=${value}`;\n const updated = content.replace(regex, nextLine);\n if (updated !== content) {\n content = updated;\n modified = true;\n }\n continue;\n }\n\n // Add newline if content doesn't end with one\n if (content && !content.endsWith(\"\\n\")) {\n content += os.EOL;\n }\n content += `${key}=${value}${os.EOL}`;\n modified = true;\n }\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\nexport function showInitFirstMessage() {\n console.log(chalk.yellow(\"No Zuro project found in this directory.\"));\n console.log(\"\");\n console.log(chalk.yellow(\"Run init first, then add modules.\"));\n console.log(\"\");\n console.log(chalk.cyan(\"npx zuro-cli init\"));\n}\n","import prompts from \"prompts\";\nimport ora from \"ora\";\nimport path from \"path\";\nimport fs from \"fs-extra\";\nimport { randomBytes } from \"node:crypto\";\nimport { fetchRegistry, fetchFile, RegistryFile } from \"../utils/registry\";\nimport { installDependencies, ensurePackageManagerAvailable } 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, showInitFirstMessage } from \"../utils/project-guard\";\n\ntype DatabaseModuleName = \"database-pg\" | \"database-mysql\";\n\nexport interface AddCommandOptions {\n dialect?: string;\n dbUrl?: string;\n yes?: boolean;\n}\n\nconst DEFAULT_DATABASE_URLS: Record<DatabaseModuleName, string> = {\n \"database-pg\": \"postgresql://postgres@localhost:5432/mydb\",\n \"database-mysql\": \"mysql://root@localhost:3306/mydb\",\n};\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\nfunction resolvePackageManager(projectRoot: string) {\n if (fs.existsSync(path.join(projectRoot, \"pnpm-lock.yaml\"))) {\n return \"pnpm\";\n }\n\n if (fs.existsSync(path.join(projectRoot, \"bun.lockb\")) || fs.existsSync(path.join(projectRoot, \"bun.lock\"))) {\n return \"bun\";\n }\n\n if (fs.existsSync(path.join(projectRoot, \"yarn.lock\"))) {\n return \"yarn\";\n }\n\n return \"npm\";\n}\n\nfunction parseDatabaseDialect(value?: string): DatabaseModuleName | null {\n const normalized = value?.trim().toLowerCase();\n if (!normalized) {\n return null;\n }\n\n if (normalized === \"pg\" || normalized === \"postgres\" || normalized === \"postgresql\" || normalized === \"database-pg\") {\n return \"database-pg\";\n }\n\n if (normalized === \"mysql\" || normalized === \"database-mysql\") {\n return \"database-mysql\";\n }\n\n return null;\n}\n\nfunction isDatabaseModule(moduleName: string): moduleName is DatabaseModuleName {\n return moduleName === \"database-pg\" || moduleName === \"database-mysql\";\n}\n\nfunction validateDatabaseUrl(rawUrl: string, moduleName: DatabaseModuleName) {\n const dbUrl = rawUrl.trim();\n if (!dbUrl) {\n throw new Error(\"Database URL cannot be empty.\");\n }\n\n let parsed: URL;\n try {\n parsed = new URL(dbUrl);\n } catch {\n throw new Error(`Invalid database URL: '${dbUrl}'.`);\n }\n\n const protocol = parsed.protocol.toLowerCase();\n if (moduleName === \"database-pg\" && protocol !== \"postgresql:\" && protocol !== \"postgres:\") {\n throw new Error(\"PostgreSQL URL must start with postgres:// or postgresql://\");\n }\n\n if (moduleName === \"database-mysql\" && protocol !== \"mysql:\") {\n throw new Error(\"MySQL URL must start with mysql://\");\n }\n\n return dbUrl;\n}\n\nasync function detectInstalledDatabaseDialect(projectRoot: string, srcDir: string): Promise<DatabaseModuleName | null> {\n const dbIndexPath = path.join(projectRoot, srcDir, \"db\", \"index.ts\");\n if (!fs.existsSync(dbIndexPath)) {\n return null;\n }\n\n const content = await fs.readFile(dbIndexPath, \"utf-8\");\n if (content.includes(\"drizzle-orm/node-postgres\") || content.includes(`from \"pg\"`)) {\n return \"database-pg\";\n }\n\n if (content.includes(\"drizzle-orm/mysql2\") || content.includes(`from \"mysql2`)) {\n return \"database-mysql\";\n }\n\n return null;\n}\n\nasync function backupDatabaseFiles(projectRoot: string, srcDir: string): Promise<string | null> {\n const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const backupRoot = path.join(projectRoot, \".zuro\", \"backups\", `database-${timestamp}`);\n const candidates = [\n path.join(projectRoot, srcDir, \"db\", \"index.ts\"),\n path.join(projectRoot, \"drizzle.config.ts\"),\n ];\n\n let copied = false;\n for (const filePath of candidates) {\n if (!fs.existsSync(filePath)) {\n continue;\n }\n\n const relativePath = path.relative(projectRoot, filePath);\n const backupPath = path.join(backupRoot, relativePath);\n await fs.ensureDir(path.dirname(backupPath));\n await fs.copyFile(filePath, backupPath);\n copied = true;\n }\n\n return copied ? backupRoot : null;\n}\n\nfunction databaseLabel(moduleName: DatabaseModuleName) {\n return moduleName === \"database-pg\" ? \"PostgreSQL\" : \"MySQL\";\n}\n\nfunction getDatabaseSetupHint(moduleName: DatabaseModuleName, dbUrl: string) {\n try {\n const parsed = new URL(dbUrl);\n const dbName = parsed.pathname.replace(/^\\/+/, \"\") || \"mydb\";\n\n if (moduleName === \"database-pg\") {\n return `createdb ${dbName}`;\n }\n\n return `mysql -e \"CREATE DATABASE IF NOT EXISTS ${dbName};\"`;\n } catch {\n return moduleName === \"database-pg\"\n ? \"createdb <database_name>\"\n : `mysql -e \"CREATE DATABASE IF NOT EXISTS <database_name>;\"`;\n }\n}\n\nfunction getModuleDocsPath(moduleName: string) {\n if (isDatabaseModule(moduleName)) {\n return \"database\";\n }\n\n return moduleName;\n}\n\nfunction escapeRegex(value: string) {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nasync function hasEnvVariable(projectRoot: string, key: string): Promise<boolean> {\n const envPath = path.join(projectRoot, \".env\");\n if (!await fs.pathExists(envPath)) {\n return false;\n }\n\n const content = await fs.readFile(envPath, \"utf-8\");\n const pattern = new RegExp(`^${escapeRegex(key)}=`, \"m\");\n return pattern.test(content);\n}\n\nasync function isLikelyEmptyDirectory(cwd: string): Promise<boolean> {\n const entries = await fs.readdir(cwd);\n const ignored = new Set([\".ds_store\", \"thumbs.db\"]);\n\n return entries.filter((entry) => !ignored.has(entry.toLowerCase())).length === 0;\n}\n\nasync function ensureSchemaExport(projectRoot: string, srcDir: string, schemaFileName: string) {\n const schemaIndexPath = path.join(projectRoot, srcDir, \"db\", \"schema\", \"index.ts\");\n if (!await fs.pathExists(schemaIndexPath)) {\n return;\n }\n\n const exportLine = `export * from \"./${schemaFileName}\";`;\n const content = await fs.readFile(schemaIndexPath, \"utf-8\");\n const normalized = content.replace(/\\r\\n/g, \"\\n\");\n const exportPattern = new RegExp(\n `^\\\\s*export\\\\s*\\\\*\\\\s*from\\\\s*[\"']\\\\./${escapeRegex(schemaFileName)}[\"'];?\\\\s*$`,\n \"m\"\n );\n\n if (exportPattern.test(normalized)) {\n return;\n }\n\n let next = normalized\n .replace(/^\\s*export\\s*\\{\\s*\\};?\\s*$/m, \"\")\n .trimEnd();\n\n if (next.length > 0) {\n next += \"\\n\\n\";\n }\n\n next += `${exportLine}\\n`;\n await fs.writeFile(schemaIndexPath, next);\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 const errorImport = `import { errorHandler, notFoundHandler } from \"./middleware/error-handler\";`;\n const hasErrorImport = content.includes(errorImport);\n const hasNotFoundUse = /app\\.use\\(\\s*notFoundHandler\\s*\\)/.test(content);\n const hasErrorUse = /app\\.use\\(\\s*errorHandler\\s*\\)/.test(content);\n let modified = false;\n let importInserted = hasErrorImport;\n\n if (!hasErrorImport) {\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 modified = true;\n importInserted = true;\n }\n }\n\n let setupInserted = hasNotFoundUse && hasErrorUse;\n if (!setupInserted) {\n const setupLines: string[] = [];\n if (!hasNotFoundUse) {\n setupLines.push(\"app.use(notFoundHandler);\");\n }\n\n if (!hasErrorUse) {\n setupLines.push(\"app.use(errorHandler);\");\n }\n\n const errorSetup = `\\n// Error handling (must be last)\\n${setupLines.join(\"\\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) + errorSetup + \"\\n\" + content.slice(exportMatch.index);\n modified = true;\n setupInserted = true;\n }\n }\n\n if (modified) {\n await fs.writeFile(appPath, content);\n }\n\n return importInserted && setupInserted;\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 const authImport = `import authRoutes from \"./routes/auth.routes\";`;\n const userImport = `import userRoutes from \"./routes/user.routes\";`;\n const hasAuthImport = content.includes(authImport);\n const hasUserImport = content.includes(userImport);\n const hasAuthRoute = /app\\.use\\(\\s*authRoutes\\s*\\)/.test(content);\n const hasUserRoute = /app\\.use\\(\\s*[\"']\\/api\\/users[\"']\\s*,\\s*userRoutes\\s*\\)/.test(content);\n let modified = false;\n let importsReady = hasAuthImport && hasUserImport;\n\n if (!importsReady) {\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 const missingImports: string[] = [];\n if (!hasAuthImport) {\n missingImports.push(authImport);\n }\n\n if (!hasUserImport) {\n missingImports.push(userImport);\n }\n\n content = content.slice(0, lastImportIndex) + `\\n${missingImports.join(\"\\n\")}` + content.slice(lastImportIndex);\n modified = true;\n importsReady = true;\n }\n }\n\n let setupReady = hasAuthRoute && hasUserRoute;\n if (!setupReady) {\n const setupLines: string[] = [];\n if (!hasAuthRoute) {\n setupLines.push(\"app.use(authRoutes);\");\n }\n\n if (!hasUserRoute) {\n setupLines.push('app.use(\"/api/users\", userRoutes);');\n }\n\n const routeSetup = `\\n// Auth routes\\n${setupLines.join(\"\\n\")}\\n`;\n const notFoundIndex = content.search(/^\\s*app\\.use\\(\\s*notFoundHandler\\s*\\);\\s*$/m);\n const errorHandlerIndex = content.search(/^\\s*app\\.use\\(\\s*errorHandler\\s*\\);\\s*$/m);\n const candidates = [notFoundIndex, errorHandlerIndex].filter((index) => index >= 0);\n const insertionIndex = candidates.length > 0\n ? Math.min(...candidates)\n : (() => {\n const exportMatch = content.match(/export default app;?\\s*$/m);\n return exportMatch?.index ?? -1;\n })();\n\n if (insertionIndex >= 0) {\n content = content.slice(0, insertionIndex) + routeSetup + \"\\n\" + content.slice(insertionIndex);\n modified = true;\n setupReady = true;\n }\n }\n\n if (modified) {\n await fs.writeFile(appPath, content);\n }\n\n return importsReady && setupReady;\n}\n\nexport const add = async (moduleName: string) => {\n const projectRoot = process.cwd();\n const projectConfig = await readZuroConfig(projectRoot);\n if (!projectConfig) {\n if (await isLikelyEmptyDirectory(projectRoot)) {\n showInitFirstMessage();\n return;\n }\n\n showNonZuroProjectMessage();\n return;\n }\n const srcDir = projectConfig.srcDir || \"src\";\n let resolvedModuleName = moduleName;\n const parsedDialect = parseDatabaseDialect(moduleName);\n if (parsedDialect) {\n resolvedModuleName = parsedDialect;\n }\n\n let customDbUrl: string | undefined;\n let usedDefaultDbUrl = false;\n let databaseBackupPath: string | null = null;\n let generatedAuthSecret = false;\n let authDatabaseDialect: DatabaseModuleName | null = null;\n\n if (resolvedModuleName === \"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 console.log(chalk.yellow(\"Operation cancelled.\"));\n return;\n }\n\n resolvedModuleName = variantResponse.variant;\n }\n\n if (isDatabaseModule(resolvedModuleName)) {\n const installedDialect = await detectInstalledDatabaseDialect(projectRoot, srcDir);\n\n if (installedDialect && installedDialect !== resolvedModuleName) {\n console.log(\n chalk.yellow(\n `\\n⚠ Existing database setup detected: ${databaseLabel(installedDialect)}.`\n )\n );\n console.log(\n chalk.yellow(\n ` Switching to ${databaseLabel(resolvedModuleName)} will overwrite db files and drizzle config.\\n`\n )\n );\n\n const switchResponse = await prompts({\n type: \"confirm\",\n name: \"proceed\",\n message: \"Continue and switch database dialect?\",\n initial: false,\n });\n\n if (!switchResponse.proceed) {\n console.log(chalk.yellow(\"Operation cancelled.\"));\n return;\n }\n\n databaseBackupPath = await backupDatabaseFiles(projectRoot, srcDir);\n }\n\n const defaultUrl = DEFAULT_DATABASE_URLS[resolvedModuleName];\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\n if (response.dbUrl === undefined) {\n console.log(chalk.yellow(\"Operation cancelled.\"));\n return;\n }\n\n const enteredUrl = response.dbUrl?.trim() || \"\";\n usedDefaultDbUrl = enteredUrl.length === 0;\n customDbUrl = validateDatabaseUrl(enteredUrl || defaultUrl, resolvedModuleName);\n }\n\n const pm = resolvePackageManager(projectRoot);\n const spinner = ora(`Checking registry for ${resolvedModuleName}...`).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 = `Checking registry for ${resolvedModuleName}...`;\n const registryContext = await fetchRegistry();\n const module = registryContext.manifest.modules[resolvedModuleName];\n\n if (!module) {\n spinner.fail(`Module '${resolvedModuleName}' not found.`);\n return;\n }\n\n spinner.succeed(`Found module: ${chalk.cyan(resolvedModuleName)}`);\n\n const moduleDeps = module.moduleDependencies || [];\n currentStep = \"module dependency resolution\";\n await resolveDependencies(moduleDeps, projectRoot);\n\n currentStep = \"dependency installation\";\n spinner.start(\"Installing dependencies...\");\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 currentStep = \"module scaffolding\";\n spinner.start(\"Scaffolding files...\");\n\n if (resolvedModuleName === \"auth\") {\n authDatabaseDialect = await detectInstalledDatabaseDialect(projectRoot, srcDir);\n }\n\n for (const file of module.files) {\n let fetchPath = file.path;\n let expectedSha256 = file.sha256;\n let expectedSize = file.size;\n\n if (\n resolvedModuleName === \"auth\"\n && file.target === \"db/schema/auth.ts\"\n && authDatabaseDialect === \"database-mysql\"\n ) {\n fetchPath = \"express/db/schema/auth.mysql.ts\";\n expectedSha256 = undefined;\n expectedSize = undefined;\n }\n\n let content = await fetchFile(fetchPath, {\n baseUrl: registryContext.fileBaseUrl,\n expectedSha256,\n expectedSize,\n });\n\n if (isDatabaseModule(resolvedModuleName) && file.target === \"../drizzle.config.ts\") {\n const normalizedSrcDir = srcDir.replace(/\\\\/g, \"/\");\n content = content.replace(\n /schema:\\s*[\"'][^\"']+[\"']/,\n `schema: \"./${normalizedSrcDir}/db/schema/*\"`\n );\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 const schemaExports = module.files\n .map((file) => file.target.replace(/\\\\/g, \"/\"))\n .filter((target) => /^db\\/schema\\/[^/]+\\.ts$/.test(target))\n .map((target) => path.posix.basename(target, \".ts\"))\n .filter((name) => name !== \"index\");\n\n for (const schemaFileName of schemaExports) {\n await ensureSchemaExport(projectRoot, srcDir, schemaFileName);\n }\n\n spinner.succeed(\"Files generated\");\n\n if (resolvedModuleName === \"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 (resolvedModuleName === \"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[resolvedModuleName as keyof typeof ENV_CONFIGS];\n if (envConfig) {\n currentStep = \"environment configuration\";\n spinner.start(\"Updating environment configuration...\");\n\n const envVars: Record<string, string> = { ...envConfig.envVars };\n if (customDbUrl && isDatabaseModule(resolvedModuleName)) {\n envVars.DATABASE_URL = customDbUrl;\n }\n\n if (resolvedModuleName === \"auth\") {\n const hasExistingSecret = await hasEnvVariable(projectRoot, \"BETTER_AUTH_SECRET\");\n if (!hasExistingSecret) {\n envVars.BETTER_AUTH_SECRET = randomBytes(32).toString(\"hex\");\n generatedAuthSecret = true;\n }\n }\n\n await updateEnvFile(projectRoot, envVars, true, {\n overwriteExisting: isDatabaseModule(resolvedModuleName),\n });\n await updateEnvSchema(projectRoot, srcDir, envConfig.schemaFields);\n\n spinner.succeed(\"Environment configured\");\n }\n\n console.log(chalk.green(`\\n✔ ${resolvedModuleName} added successfully!\\n`));\n\n if (databaseBackupPath) {\n console.log(chalk.blue(`ℹ Backup created at: ${databaseBackupPath}\\n`));\n }\n\n const docsPath = getModuleDocsPath(resolvedModuleName);\n const docsUrl = `https://zuro-cli.devbybriyan.com/docs/${docsPath}`;\n console.log(chalk.blue(`ℹ Docs: ${docsUrl}`));\n\n if (isDatabaseModule(resolvedModuleName)) {\n if (usedDefaultDbUrl) {\n console.log(chalk.yellow(\"ℹ Review DATABASE_URL in .env if your local DB config differs.\"));\n }\n\n const setupHint = getDatabaseSetupHint(\n resolvedModuleName,\n customDbUrl || DEFAULT_DATABASE_URLS[resolvedModuleName]\n );\n console.log(chalk.yellow(`ℹ Ensure DB exists: ${setupHint}`));\n console.log(chalk.yellow(\"ℹ Run migrations: npx drizzle-kit generate && npx drizzle-kit migrate\"));\n }\n\n if (resolvedModuleName === \"auth\") {\n if (generatedAuthSecret) {\n console.log(chalk.yellow(\"ℹ BETTER_AUTH_SECRET was generated automatically.\"));\n } else {\n console.log(chalk.yellow(\"ℹ Review BETTER_AUTH_SECRET and BETTER_AUTH_URL in .env.\"));\n }\n\n console.log(chalk.yellow(\"ℹ Run migrations: npx drizzle-kit generate && npx drizzle-kit migrate\"));\n }\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 console.log(chalk.cyan(` npx zuro-cli add ${resolvedModuleName}`));\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\nasync function setupPrettier(targetDir: string) {\n const prettierConfigPath = path.join(targetDir, \".prettierrc\");\n const prettierIgnorePath = path.join(targetDir, \".prettierignore\");\n\n if (!await fs.pathExists(prettierConfigPath)) {\n const prettierConfig = {\n semi: true,\n singleQuote: false,\n trailingComma: \"es5\",\n printWidth: 100,\n tabWidth: 2,\n };\n await fs.writeJson(prettierConfigPath, prettierConfig, { spaces: 2 });\n }\n\n if (!await fs.pathExists(prettierIgnorePath)) {\n const ignoreContent = `node_modules\ndist\nbuild\ncoverage\n.next\npnpm-lock.yaml\npackage-lock.json\nbun.lock\nbun.lockb\n`;\n await fs.writeFile(prettierIgnorePath, ignoreContent);\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 let enablePrettier = false;\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 type: \"confirm\",\n name: \"prettier\",\n message: \"Setup Prettier?\",\n initial: true,\n },\n ]);\n\n if (response.pm === undefined) {\n console.log(chalk.red(\"Operation cancelled.\"));\n return;\n }\n\n pm = response.pm;\n enablePrettier = response.prettier === true;\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, { enablePrettier });\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 if (enablePrettier) {\n await installDependencies(pm, [\"prettier\"], targetDir, { dev: true });\n }\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 if (enablePrettier) {\n currentStep = \"prettier setup\";\n await setupPrettier(targetDir);\n }\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 options: { enablePrettier?: boolean } = {}\n) {\n const pkgPath = path.join(cwd, \"package.json\");\n if (force || !await fs.pathExists(pkgPath)) {\n const scripts: Record<string, string> = {\n \"dev\": `tsx watch ${srcDir}/server.ts`,\n \"build\": \"tsc\",\n \"start\": \"node dist/server.js\"\n };\n\n if (options.enablePrettier) {\n scripts[\"format\"] = \"prettier --write .\";\n scripts[\"format:check\"] = \"prettier --check .\";\n }\n\n await fs.writeJson(pkgPath, {\n name: normalizePackageName(packageName),\n version: \"0.0.1\",\n private: true,\n scripts\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 (\n cwd: string,\n variables: Record<string, string>,\n createIfMissing = true,\n options: { overwriteExisting?: boolean } = {}\n) => {\n const envPath = path.join(cwd, \".env\");\n const overwriteExisting = options.overwriteExisting ?? false;\n\n let content = \"\";\n if (fs.existsSync(envPath)) {\n content = await fs.readFile(envPath, \"utf-8\");\n } else if (!createIfMissing) {\r\n return;\r\n }\r\n\r\n let modified = false;\n\n for (const [key, value] of Object.entries(variables)) {\n const escapedKey = key.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n const regex = new RegExp(`^${escapedKey}=.*$`, \"m\");\n\n if (regex.test(content)) {\n if (!overwriteExisting) {\n continue;\n }\n\n const nextLine = `${key}=${value}`;\n const updated = content.replace(regex, nextLine);\n if (updated !== content) {\n content = updated;\n modified = true;\n }\n continue;\n }\n\n // Add newline if content doesn't end with one\n if (content && !content.endsWith(\"\\n\")) {\n content += os.EOL;\n }\n content += `${key}=${value}${os.EOL}`;\n modified = true;\n }\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\nexport function showInitFirstMessage() {\n console.log(chalk.yellow(\"No Zuro project found in this directory.\"));\n console.log(\"\");\n console.log(chalk.yellow(\"Run init first, then add modules.\"));\n console.log(\"\");\n console.log(chalk.cyan(\"npx zuro-cli init\"));\n}\n","import prompts from \"prompts\";\nimport ora from \"ora\";\nimport path from \"path\";\nimport fs from \"fs-extra\";\nimport { randomBytes } from \"node:crypto\";\nimport { fetchRegistry, fetchFile, RegistryFile } from \"../utils/registry\";\nimport { installDependencies, ensurePackageManagerAvailable } 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, showInitFirstMessage } from \"../utils/project-guard\";\n\ntype DatabaseModuleName = \"database-pg\" | \"database-mysql\";\n\nexport interface AddCommandOptions {\n dialect?: string;\n dbUrl?: string;\n yes?: boolean;\n}\n\nconst DEFAULT_DATABASE_URLS: Record<DatabaseModuleName, string> = {\n \"database-pg\": \"postgresql://postgres@localhost:5432/mydb\",\n \"database-mysql\": \"mysql://root@localhost:3306/mydb\",\n};\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\nfunction resolvePackageManager(projectRoot: string) {\n if (fs.existsSync(path.join(projectRoot, \"pnpm-lock.yaml\"))) {\n return \"pnpm\";\n }\n\n if (fs.existsSync(path.join(projectRoot, \"bun.lockb\")) || fs.existsSync(path.join(projectRoot, \"bun.lock\"))) {\n return \"bun\";\n }\n\n if (fs.existsSync(path.join(projectRoot, \"yarn.lock\"))) {\n return \"yarn\";\n }\n\n return \"npm\";\n}\n\nfunction parseDatabaseDialect(value?: string): DatabaseModuleName | null {\n const normalized = value?.trim().toLowerCase();\n if (!normalized) {\n return null;\n }\n\n if (normalized === \"pg\" || normalized === \"postgres\" || normalized === \"postgresql\" || normalized === \"database-pg\") {\n return \"database-pg\";\n }\n\n if (normalized === \"mysql\" || normalized === \"database-mysql\") {\n return \"database-mysql\";\n }\n\n return null;\n}\n\nfunction isDatabaseModule(moduleName: string): moduleName is DatabaseModuleName {\n return moduleName === \"database-pg\" || moduleName === \"database-mysql\";\n}\n\nfunction validateDatabaseUrl(rawUrl: string, moduleName: DatabaseModuleName) {\n const dbUrl = rawUrl.trim();\n if (!dbUrl) {\n throw new Error(\"Database URL cannot be empty.\");\n }\n\n let parsed: URL;\n try {\n parsed = new URL(dbUrl);\n } catch {\n throw new Error(`Invalid database URL: '${dbUrl}'.`);\n }\n\n const protocol = parsed.protocol.toLowerCase();\n if (moduleName === \"database-pg\" && protocol !== \"postgresql:\" && protocol !== \"postgres:\") {\n throw new Error(\"PostgreSQL URL must start with postgres:// or postgresql://\");\n }\n\n if (moduleName === \"database-mysql\" && protocol !== \"mysql:\") {\n throw new Error(\"MySQL URL must start with mysql://\");\n }\n\n return dbUrl;\n}\n\nasync function detectInstalledDatabaseDialect(projectRoot: string, srcDir: string): Promise<DatabaseModuleName | null> {\n const dbIndexPath = path.join(projectRoot, srcDir, \"db\", \"index.ts\");\n if (!fs.existsSync(dbIndexPath)) {\n return null;\n }\n\n const content = await fs.readFile(dbIndexPath, \"utf-8\");\n if (content.includes(\"drizzle-orm/node-postgres\") || content.includes(`from \"pg\"`)) {\n return \"database-pg\";\n }\n\n if (content.includes(\"drizzle-orm/mysql2\") || content.includes(`from \"mysql2`)) {\n return \"database-mysql\";\n }\n\n return null;\n}\n\nasync function backupDatabaseFiles(projectRoot: string, srcDir: string): Promise<string | null> {\n const timestamp = new Date().toISOString().replace(/[:.]/g, \"-\");\n const backupRoot = path.join(projectRoot, \".zuro\", \"backups\", `database-${timestamp}`);\n const candidates = [\n path.join(projectRoot, srcDir, \"db\", \"index.ts\"),\n path.join(projectRoot, \"drizzle.config.ts\"),\n ];\n\n let copied = false;\n for (const filePath of candidates) {\n if (!fs.existsSync(filePath)) {\n continue;\n }\n\n const relativePath = path.relative(projectRoot, filePath);\n const backupPath = path.join(backupRoot, relativePath);\n await fs.ensureDir(path.dirname(backupPath));\n await fs.copyFile(filePath, backupPath);\n copied = true;\n }\n\n return copied ? backupRoot : null;\n}\n\nfunction databaseLabel(moduleName: DatabaseModuleName) {\n return moduleName === \"database-pg\" ? \"PostgreSQL\" : \"MySQL\";\n}\n\nfunction getDatabaseSetupHint(moduleName: DatabaseModuleName, dbUrl: string) {\n try {\n const parsed = new URL(dbUrl);\n const dbName = parsed.pathname.replace(/^\\/+/, \"\") || \"mydb\";\n\n if (moduleName === \"database-pg\") {\n return `createdb ${dbName}`;\n }\n\n return `mysql -e \"CREATE DATABASE IF NOT EXISTS ${dbName};\"`;\n } catch {\n return moduleName === \"database-pg\"\n ? \"createdb <database_name>\"\n : `mysql -e \"CREATE DATABASE IF NOT EXISTS <database_name>;\"`;\n }\n}\n\nfunction getModuleDocsPath(moduleName: string) {\n if (isDatabaseModule(moduleName)) {\n return \"database\";\n }\n\n return moduleName;\n}\n\nfunction escapeRegex(value: string) {\n return value.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\nasync function hasEnvVariable(projectRoot: string, key: string): Promise<boolean> {\n const envPath = path.join(projectRoot, \".env\");\n if (!await fs.pathExists(envPath)) {\n return false;\n }\n\n const content = await fs.readFile(envPath, \"utf-8\");\n const pattern = new RegExp(`^${escapeRegex(key)}=`, \"m\");\n return pattern.test(content);\n}\n\nasync function isLikelyEmptyDirectory(cwd: string): Promise<boolean> {\n const entries = await fs.readdir(cwd);\n const ignored = new Set([\".ds_store\", \"thumbs.db\"]);\n\n return entries.filter((entry) => !ignored.has(entry.toLowerCase())).length === 0;\n}\n\nasync function ensureSchemaExport(projectRoot: string, srcDir: string, schemaFileName: string) {\n const schemaIndexPath = path.join(projectRoot, srcDir, \"db\", \"schema\", \"index.ts\");\n if (!await fs.pathExists(schemaIndexPath)) {\n return;\n }\n\n const exportLine = `export * from \"./${schemaFileName}\";`;\n const content = await fs.readFile(schemaIndexPath, \"utf-8\");\n const normalized = content.replace(/\\r\\n/g, \"\\n\");\n const exportPattern = new RegExp(\n `^\\\\s*export\\\\s*\\\\*\\\\s*from\\\\s*[\"']\\\\./${escapeRegex(schemaFileName)}[\"'];?\\\\s*$`,\n \"m\"\n );\n\n if (exportPattern.test(normalized)) {\n return;\n }\n\n let next = normalized\n .replace(/^\\s*export\\s*\\{\\s*\\};?\\s*$/m, \"\")\n .trimEnd();\n\n if (next.length > 0) {\n next += \"\\n\\n\";\n }\n\n next += `${exportLine}\\n`;\n await fs.writeFile(schemaIndexPath, next);\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 const errorImport = `import { errorHandler, notFoundHandler } from \"./middleware/error-handler\";`;\n const hasErrorImport = content.includes(errorImport);\n const hasNotFoundUse = /app\\.use\\(\\s*notFoundHandler\\s*\\)/.test(content);\n const hasErrorUse = /app\\.use\\(\\s*errorHandler\\s*\\)/.test(content);\n let modified = false;\n let importInserted = hasErrorImport;\n\n if (!hasErrorImport) {\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 modified = true;\n importInserted = true;\n }\n }\n\n let setupInserted = hasNotFoundUse && hasErrorUse;\n if (!setupInserted) {\n const setupLines: string[] = [];\n if (!hasNotFoundUse) {\n setupLines.push(\"app.use(notFoundHandler);\");\n }\n\n if (!hasErrorUse) {\n setupLines.push(\"app.use(errorHandler);\");\n }\n\n const errorSetup = `\\n// Error handling (must be last)\\n${setupLines.join(\"\\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) + errorSetup + \"\\n\" + content.slice(exportMatch.index);\n modified = true;\n setupInserted = true;\n }\n }\n\n if (modified) {\n await fs.writeFile(appPath, content);\n }\n\n return importInserted && setupInserted;\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 if (!await fs.pathExists(appPath)) {\n return false;\n }\n\n let appContent = await fs.readFile(appPath, \"utf-8\");\n const authHandlerImport = `import { toNodeHandler } from \"better-auth/node\";`;\n const authImport = `import { auth } from \"./lib/auth\";`;\n const userImport = `import userRoutes from \"./routes/user.routes\";`;\n\n let appModified = false;\n\n const appendImport = (source: string, line: string) => {\n if (source.includes(line)) {\n return { source, inserted: true };\n }\n\n const importRegex = /^import .+ from .+;?\\s*$/gm;\n let lastImportIndex = 0;\n let match;\n while ((match = importRegex.exec(source)) !== null) {\n lastImportIndex = match.index + match[0].length;\n }\n\n if (lastImportIndex <= 0) {\n return { source, inserted: false };\n }\n\n return {\n source: source.slice(0, lastImportIndex) + `\\n${line}` + source.slice(lastImportIndex),\n inserted: true,\n };\n };\n\n for (const importLine of [authHandlerImport, authImport]) {\n const next = appendImport(appContent, importLine);\n if (!next.inserted) {\n return false;\n }\n\n if (next.source !== appContent) {\n appContent = next.source;\n appModified = true;\n }\n }\n\n const hasAuthMount = /toNodeHandler\\(\\s*auth\\s*\\)/.test(appContent)\n && /\\/api\\/auth/.test(appContent);\n if (!hasAuthMount) {\n const authMountLine = \"app.all(/^\\\\/api\\\\/auth(?:\\\\/.*)?$/, toNodeHandler(auth));\\n\";\n const jsonIndex = appContent.search(/^\\s*app\\.use\\(\\s*express\\.json\\(\\)\\s*\\);\\s*$/m);\n\n let insertionIndex = jsonIndex;\n if (insertionIndex < 0) {\n const healthIndex = appContent.search(/^\\s*app\\.get\\(\\s*[\"']\\/health[\"']\\s*,/m);\n insertionIndex = healthIndex;\n }\n\n if (insertionIndex < 0) {\n const exportMatch = appContent.match(/export default app;?\\s*$/m);\n insertionIndex = exportMatch?.index ?? -1;\n }\n\n if (insertionIndex < 0) {\n return false;\n }\n\n appContent = appContent.slice(0, insertionIndex) + authMountLine + appContent.slice(insertionIndex);\n appModified = true;\n }\n\n const routeIndexPath = path.join(projectRoot, srcDir, \"routes\", \"index.ts\");\n if (await fs.pathExists(routeIndexPath)) {\n let routeContent = await fs.readFile(routeIndexPath, \"utf-8\");\n let routeModified = false;\n\n const userImportResult = appendImport(routeContent, userImport);\n if (!userImportResult.inserted) {\n return false;\n }\n\n if (userImportResult.source !== routeContent) {\n routeContent = userImportResult.source;\n routeModified = true;\n }\n\n const hasUserRoute = /rootRouter\\.use\\(\\s*[\"']\\/users[\"']\\s*,\\s*userRoutes\\s*\\)/.test(routeContent);\n if (!hasUserRoute) {\n const routeSetup = `\\n// User routes\\nrootRouter.use(\"/users\", userRoutes);\\n`;\n const exportMatch = routeContent.match(/export default rootRouter;?\\s*$/m);\n\n if (!exportMatch || exportMatch.index === undefined) {\n return false;\n }\n\n routeContent = routeContent.slice(0, exportMatch.index) + routeSetup + \"\\n\" + routeContent.slice(exportMatch.index);\n routeModified = true;\n }\n\n if (routeModified) {\n await fs.writeFile(routeIndexPath, routeContent);\n }\n } else {\n const hasUserRoute = /app\\.use\\(\\s*[\"']\\/api\\/users[\"']\\s*,\\s*userRoutes\\s*\\)/.test(appContent);\n if (!hasUserRoute) {\n const exportMatch = appContent.match(/export default app;?\\s*$/m);\n if (!exportMatch || exportMatch.index === undefined) {\n return false;\n }\n\n const routeSetup = `\\n// User routes\\napp.use(\"/api/users\", userRoutes);\\n`;\n appContent = appContent.slice(0, exportMatch.index) + routeSetup + \"\\n\" + appContent.slice(exportMatch.index);\n appModified = true;\n }\n\n const userImportResult = appendImport(appContent, userImport);\n if (!userImportResult.inserted) {\n return false;\n }\n\n if (userImportResult.source !== appContent) {\n appContent = userImportResult.source;\n appModified = true;\n }\n }\n\n if (appModified) {\n await fs.writeFile(appPath, appContent);\n }\n\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 if (await isLikelyEmptyDirectory(projectRoot)) {\n showInitFirstMessage();\n return;\n }\n\n showNonZuroProjectMessage();\n return;\n }\n const srcDir = projectConfig.srcDir || \"src\";\n let resolvedModuleName = moduleName;\n const parsedDialect = parseDatabaseDialect(moduleName);\n if (parsedDialect) {\n resolvedModuleName = parsedDialect;\n }\n\n let customDbUrl: string | undefined;\n let usedDefaultDbUrl = false;\n let databaseBackupPath: string | null = null;\n let generatedAuthSecret = false;\n let authDatabaseDialect: DatabaseModuleName | null = null;\n\n if (resolvedModuleName === \"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 console.log(chalk.yellow(\"Operation cancelled.\"));\n return;\n }\n\n resolvedModuleName = variantResponse.variant;\n }\n\n if (isDatabaseModule(resolvedModuleName)) {\n const installedDialect = await detectInstalledDatabaseDialect(projectRoot, srcDir);\n\n if (installedDialect && installedDialect !== resolvedModuleName) {\n console.log(\n chalk.yellow(\n `\\n⚠ Existing database setup detected: ${databaseLabel(installedDialect)}.`\n )\n );\n console.log(\n chalk.yellow(\n ` Switching to ${databaseLabel(resolvedModuleName)} will overwrite db files and drizzle config.\\n`\n )\n );\n\n const switchResponse = await prompts({\n type: \"confirm\",\n name: \"proceed\",\n message: \"Continue and switch database dialect?\",\n initial: false,\n });\n\n if (!switchResponse.proceed) {\n console.log(chalk.yellow(\"Operation cancelled.\"));\n return;\n }\n\n databaseBackupPath = await backupDatabaseFiles(projectRoot, srcDir);\n }\n\n const defaultUrl = DEFAULT_DATABASE_URLS[resolvedModuleName];\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\n if (response.dbUrl === undefined) {\n console.log(chalk.yellow(\"Operation cancelled.\"));\n return;\n }\n\n const enteredUrl = response.dbUrl?.trim() || \"\";\n usedDefaultDbUrl = enteredUrl.length === 0;\n customDbUrl = validateDatabaseUrl(enteredUrl || defaultUrl, resolvedModuleName);\n }\n\n const pm = resolvePackageManager(projectRoot);\n const spinner = ora(`Checking registry for ${resolvedModuleName}...`).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 = `Checking registry for ${resolvedModuleName}...`;\n const registryContext = await fetchRegistry();\n const module = registryContext.manifest.modules[resolvedModuleName];\n\n if (!module) {\n spinner.fail(`Module '${resolvedModuleName}' not found.`);\n return;\n }\n\n spinner.succeed(`Found module: ${chalk.cyan(resolvedModuleName)}`);\n\n const moduleDeps = module.moduleDependencies || [];\n currentStep = \"module dependency resolution\";\n await resolveDependencies(moduleDeps, projectRoot);\n\n currentStep = \"dependency installation\";\n spinner.start(\"Installing dependencies...\");\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 currentStep = \"module scaffolding\";\n spinner.start(\"Scaffolding files...\");\n\n if (resolvedModuleName === \"auth\") {\n authDatabaseDialect = await detectInstalledDatabaseDialect(projectRoot, srcDir);\n }\n\n for (const file of module.files) {\n let fetchPath = file.path;\n let expectedSha256 = file.sha256;\n let expectedSize = file.size;\n\n if (\n resolvedModuleName === \"auth\"\n && file.target === \"db/schema/auth.ts\"\n && authDatabaseDialect === \"database-mysql\"\n ) {\n fetchPath = \"express/db/schema/auth.mysql.ts\";\n expectedSha256 = undefined;\n expectedSize = undefined;\n }\n\n let content = await fetchFile(fetchPath, {\n baseUrl: registryContext.fileBaseUrl,\n expectedSha256,\n expectedSize,\n });\n\n if (isDatabaseModule(resolvedModuleName) && file.target === \"../drizzle.config.ts\") {\n const normalizedSrcDir = srcDir.replace(/\\\\/g, \"/\");\n content = content.replace(\n /schema:\\s*[\"'][^\"']+[\"']/,\n `schema: \"./${normalizedSrcDir}/db/schema/*\"`\n );\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 const schemaExports = module.files\n .map((file) => file.target.replace(/\\\\/g, \"/\"))\n .filter((target) => /^db\\/schema\\/[^/]+\\.ts$/.test(target))\n .map((target) => path.posix.basename(target, \".ts\"))\n .filter((name) => name !== \"index\");\n\n for (const schemaFileName of schemaExports) {\n await ensureSchemaExport(projectRoot, srcDir, schemaFileName);\n }\n\n spinner.succeed(\"Files generated\");\n\n if (resolvedModuleName === \"auth\") {\n spinner.start(\"Configuring routes...\");\n const injected = await injectAuthRoutes(projectRoot, srcDir);\n if (injected) {\n spinner.succeed(\"Routes configured\");\n } else {\n spinner.warn(\"Could not configure routes automatically\");\n }\n }\n\n if (resolvedModuleName === \"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[resolvedModuleName as keyof typeof ENV_CONFIGS];\n if (envConfig) {\n currentStep = \"environment configuration\";\n spinner.start(\"Updating environment configuration...\");\n\n const envVars: Record<string, string> = { ...envConfig.envVars };\n if (customDbUrl && isDatabaseModule(resolvedModuleName)) {\n envVars.DATABASE_URL = customDbUrl;\n }\n\n if (resolvedModuleName === \"auth\") {\n const hasExistingSecret = await hasEnvVariable(projectRoot, \"BETTER_AUTH_SECRET\");\n if (!hasExistingSecret) {\n envVars.BETTER_AUTH_SECRET = randomBytes(32).toString(\"hex\");\n generatedAuthSecret = true;\n }\n }\n\n await updateEnvFile(projectRoot, envVars, true, {\n overwriteExisting: isDatabaseModule(resolvedModuleName),\n });\n await updateEnvSchema(projectRoot, srcDir, envConfig.schemaFields);\n\n spinner.succeed(\"Environment configured\");\n }\n\n console.log(chalk.green(`\\n✔ ${resolvedModuleName} added successfully!\\n`));\n\n if (databaseBackupPath) {\n console.log(chalk.blue(`ℹ Backup created at: ${databaseBackupPath}\\n`));\n }\n\n const docsPath = getModuleDocsPath(resolvedModuleName);\n const docsUrl = `https://zuro-cli.devbybriyan.com/docs/${docsPath}`;\n console.log(chalk.blue(`ℹ Docs: ${docsUrl}`));\n\n if (isDatabaseModule(resolvedModuleName)) {\n if (usedDefaultDbUrl) {\n console.log(chalk.yellow(\"ℹ Review DATABASE_URL in .env if your local DB config differs.\"));\n }\n\n const setupHint = getDatabaseSetupHint(\n resolvedModuleName,\n customDbUrl || DEFAULT_DATABASE_URLS[resolvedModuleName]\n );\n console.log(chalk.yellow(`ℹ Ensure DB exists: ${setupHint}`));\n console.log(chalk.yellow(\"ℹ Run migrations: npx drizzle-kit generate && npx drizzle-kit migrate\"));\n }\n\n if (resolvedModuleName === \"auth\") {\n if (generatedAuthSecret) {\n console.log(chalk.yellow(\"ℹ BETTER_AUTH_SECRET was generated automatically.\"));\n } else {\n console.log(chalk.yellow(\"ℹ Review BETTER_AUTH_SECRET and BETTER_AUTH_URL in .env.\"));\n }\n\n console.log(chalk.yellow(\"ℹ Run migrations: npx drizzle-kit generate && npx drizzle-kit migrate\"));\n }\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 console.log(chalk.cyan(` npx zuro-cli add ${resolvedModuleName}`));\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.7",
3
+ "version": "0.0.2-beta.9",
4
4
  "description": "The backend builder for busy developers.",
5
5
  "bin": {
6
6
  "zuro-cli": "./dist/index.js"