UNPKG

microfox

Version:

Universal CLI tool for creating modern TypeScript packages with npm availability checking

263 lines (259 loc) 10.3 kB
#!/usr/bin/env node // src/commands/install.ts import { Command } from "commander"; // src/utils/experimental-installer.ts import fs from "fs"; import path from "path"; import { execSync } from "child_process"; import chalk from "chalk"; var CWD_PACKAGE_JSON = path.join(process.cwd(), "package.json"); var CWD_NODE_MODULES = path.join(process.cwd(), "node_modules"); var MICROFOX_NODE_MODULES; function log(message, isError = false, isWarning = false) { const timestamp = (/* @__PURE__ */ new Date()).toLocaleTimeString(); let prefix; if (isError) { prefix = chalk.red(`\u274C [install-microfox ${timestamp}]`); } else if (isWarning) { prefix = chalk.yellow(`\u26A0\uFE0F [install-microfox ${timestamp}]`); } else { prefix = chalk.blue(`\u2139\uFE0F [install-microfox ${timestamp}]`); } console.log(`${prefix} ${message}`); } function logSuccess(message) { const timestamp = (/* @__PURE__ */ new Date()).toLocaleTimeString(); console.log(chalk.green(`\u2705 [install-microfox ${timestamp}] ${message}`)); } function logSection(title) { console.log("\n" + "=".repeat(60)); console.log(` ${title}`); console.log("=".repeat(60)); } function findSourceDir(targetDirName) { let currentDir = process.cwd(); for (let i = 0; i < 10; i++) { const gitDir = path.join(currentDir, ".git"); if (fs.existsSync(gitDir)) { const parentDir = path.dirname(currentDir); const microfoxDir = path.join(parentDir, targetDirName); if (fs.existsSync(microfoxDir)) { return microfoxDir; } } const parent = path.dirname(currentDir); if (parent === currentDir) { break; } currentDir = parent; } return null; } function copyDirectory(src, dest) { try { const normalizedSrc = path.resolve(src); const normalizedDest = path.resolve(dest); log(`Copying from: ${normalizedSrc}`); log(`Copying to: ${normalizedDest}`); if (!fs.existsSync(normalizedDest)) { fs.mkdirSync(normalizedDest, { recursive: true }); } const isWindows = process.platform === "win32"; if (isWindows) { try { execSync(`robocopy "${normalizedSrc}" "${normalizedDest}" /E /NFL /NDL /NJH /NJS /nc /ns /np`, { stdio: "pipe" }); } catch (error) { if (error.status !== 1 && error.status !== 0) { throw error; } } } else { execSync(`cp -r "${normalizedSrc}/." "${normalizedDest}"`, { stdio: "pipe" }); } if (fs.existsSync(normalizedDest) && fs.readdirSync(normalizedDest).length > 0) { log(`\u2705 Copied ${normalizedSrc} -> ${normalizedDest}`); return true; } else { log(`\u274C Copy verification failed: destination is empty`); return false; } } catch (error) { log(`\u274C Failed to copy ${src} -> ${dest}: ${error.message}`); return false; } } function updatePackageJson(packageName) { var _a, _b, _c; try { log(`Updating package.json to add ${packageName} with "*" version...`); if (!fs.existsSync(CWD_PACKAGE_JSON)) { log(`Package.json file not found at: ${CWD_PACKAGE_JSON}`, true); return false; } const packageJson = JSON.parse(fs.readFileSync(CWD_PACKAGE_JSON, "utf8")); const existingVersion = ((_a = packageJson.dependencies) == null ? void 0 : _a[packageName]) || ((_b = packageJson.devDependencies) == null ? void 0 : _b[packageName]); if (existingVersion && existingVersion !== "*") { log(`Package ${packageName} already exists with version: ${existingVersion}`, false, true); log(`Updating to "*" for local development...`, false, true); } if (!packageJson.dependencies) { packageJson.dependencies = {}; } packageJson.dependencies[packageName] = "*"; if ((_c = packageJson.devDependencies) == null ? void 0 : _c[packageName]) { delete packageJson.devDependencies[packageName]; log(`Moved ${packageName} from devDependencies to dependencies`); } fs.writeFileSync(CWD_PACKAGE_JSON, JSON.stringify(packageJson, null, 2) + "\n"); logSuccess(`Added ${packageName}: "*" to package.json`); return true; } catch (error) { if (error.code === "ENOENT") { log(`Package.json file not found at: ${CWD_PACKAGE_JSON}`, true); } else if (error instanceof SyntaxError) { log(`Invalid JSON in package.json: ${error.message}`, true); } else if (error.code === "EACCES") { log(`Permission denied writing to package.json`, true); } else { log(`Failed to update package.json: ${error.message}`, true); } return false; } } function installSpecificPackage(packageName) { logSection(`Installing Specific Package: ${packageName}`); if (!packageName || typeof packageName !== "string" || !packageName.startsWith("@microfox/")) { log(`Invalid package name format: "${packageName}". Must start with "@microfox/"`, true); process.exit(1); } const packageShortName = packageName.replace("@microfox/", ""); if (!packageShortName || packageShortName.trim() === "") { log(`Invalid package name: "${packageName}"`, true); process.exit(1); } const microfoxDir = path.join(MICROFOX_NODE_MODULES, "@microfox"); const srcDir = path.join(microfoxDir, packageShortName); log(`Searching for package: ${packageName}`); log(`Source directory: ${srcDir}`); if (!fs.existsSync(microfoxDir)) { log(`Microfox packages directory not found at: ${microfoxDir}`, true); process.exit(1); } if (!fs.existsSync(srcDir)) { log(`Package "${packageName}" not found in source packages`, true); log(`Searched in: ${srcDir}`, true); process.exit(1); } if (!updatePackageJson(packageName)) { process.exit(1); } const microfoxScopeDir = path.join(CWD_NODE_MODULES, "@microfox"); if (!fs.existsSync(microfoxScopeDir)) { fs.mkdirSync(microfoxScopeDir, { recursive: true }); } const destDir = path.join(CWD_NODE_MODULES, "@microfox", packageShortName); log(`Copying package files...`); if (copyDirectory(srcDir, destDir)) { logSection(`\u2705 SUCCESS`); logSuccess(`Package ${packageName} installed for local development!`); log(`Package location: ${destDir}`); } else { log(`Failed to copy package files`, true); process.exit(1); } } function installAllPackages() { log('Installing all @microfox/* packages with "*" version from package.json...'); const packageJson = JSON.parse(fs.readFileSync(CWD_PACKAGE_JSON, "utf8")); const dependencies = { ...packageJson.dependencies, ...packageJson.devDependencies }; const microfoxPackages = Object.entries(dependencies).filter(([name, version]) => name.startsWith("@microfox/") && version === "*").map(([name]) => name); if (microfoxPackages.length === 0) { log('\u2139\uFE0F No @microfox/* packages with "*" version found in package.json'); return; } log(`Found ${microfoxPackages.length} @microfox/* packages to install:`); microfoxPackages.forEach((pkg) => log(` - ${pkg}`)); const microfoxScopeDir = path.join(CWD_NODE_MODULES, "@microfox"); if (!fs.existsSync(microfoxScopeDir)) { fs.mkdirSync(microfoxScopeDir, { recursive: true }); } let successCount = 0; let failureCount = 0; for (const packageName of microfoxPackages) { const packageShortName = packageName.replace("@microfox/", ""); const srcDir = path.join(MICROFOX_NODE_MODULES, "@microfox", packageShortName); const destDir = path.join(CWD_NODE_MODULES, "@microfox", packageShortName); if (!fs.existsSync(srcDir)) { log(`\u26A0\uFE0F Package ${packageName} not found in source node_modules, skipping...`); failureCount++; continue; } if (copyDirectory(srcDir, destDir)) { successCount++; } else { failureCount++; } } log(` \u{1F4CA} Installation Summary:`); log(` \u2705 Successfully installed: ${successCount} packages`); if (failureCount > 0) { log(` \u274C Failed to install: ${failureCount} packages`); } } async function runExperimentalInstall(packages, targetDirName) { try { logSection("Microfox Local Package Installer (Experimental)"); log(`Started at: ${(/* @__PURE__ */ new Date()).toLocaleString()}`); log(`Working directory: ${process.cwd()}`); const sourceDir = findSourceDir(targetDirName); if (!sourceDir) { log(`Could not find source directory '${targetDirName}' in any parent of a .git directory.`, true); log(`Searched up to 10 levels from ${process.cwd()}`, true); process.exit(1); } log(`Found source directory at: ${sourceDir}`); MICROFOX_NODE_MODULES = path.join(sourceDir, "node_modules"); if (!fs.existsSync(MICROFOX_NODE_MODULES)) { log(`Source node_modules directory not found at: ${MICROFOX_NODE_MODULES}`, true); log(`Please run 'npm install' or 'pnpm install' in ${sourceDir}`, true); process.exit(1); } if (!fs.existsSync(CWD_PACKAGE_JSON)) { log(`package.json not found in current directory: ${CWD_PACKAGE_JSON}`, true); process.exit(1); } if (packages.length > 0) { log(`Installing ${packages.length} specific package(s)...`); for (let i = 0; i < packages.length; i++) { const packageName = packages[i]; log(` [${i + 1}/${packages.length}] Processing: ${packageName}`); installSpecificPackage(packageName); } logSection("\u{1F389} All Specified Packages Installed Successfully"); } else { installAllPackages(); } } catch (error) { log("", true); log(`Unexpected error occurred: ${error.message}`, true); if (error.stack) { log(`Stack trace: ${error.stack}`, true); } process.exit(1); } } // src/commands/install.ts var installCommand = new Command("install").description("Install packages for local development.").argument("[packages...]", "Specific packages to install").option("--experimental", "Enable experimental features").option("--target <name>", "Specify the target source directory name", "Microfox").action(async (packages, options) => { if (options.experimental) { await runExperimentalInstall(packages, options.target); } else { console.log("This command is only available with the --experimental flag."); process.exit(1); } }); export { installCommand }; //# sourceMappingURL=chunk-ARAHSYJI.mjs.map