UNPKG

@kya-os/create-mcp-i-app

Version:

Bootstrap MCP applications with identity features (temporary - use @kya-os/create-mcpi-app after Oct 7)

106 lines 3.46 kB
import fs from "fs-extra"; import path from "path"; /** * Validate project name meets requirements */ export function validateProjectName(name) { const issues = []; // Check if name is empty if (!name || name.trim().length === 0) { issues.push("Project name cannot be empty"); return { valid: false, issues }; } const trimmedName = name.trim(); // Check length if (trimmedName.length < 1) { issues.push("Project name must be at least 1 character long"); } if (trimmedName.length > 214) { issues.push("Project name must be less than 214 characters"); } // Check for invalid characters (npm package name rules) if (!/^[a-z0-9@._/-]+$/.test(trimmedName)) { issues.push("Project name can only contain lowercase letters, numbers, and the characters @._/-"); } // Check if it starts with . or _ if (trimmedName.startsWith(".") || trimmedName.startsWith("_")) { issues.push("Project name cannot start with . or _"); } // Check for reserved names const reservedNames = [ "node_modules", "favicon.ico", "package.json", "package-lock.json", "yarn.lock", "pnpm-lock.yaml", ".git", ".gitignore", ".env", "readme", "readme.md", "readme.txt", "license", "license.md", "license.txt", "changelog", "changelog.md", "changelog.txt", ]; if (reservedNames.includes(trimmedName.toLowerCase())) { issues.push(`"${trimmedName}" is a reserved name and cannot be used as a project name`); } // Check for scoped package format if (trimmedName.startsWith("@")) { const parts = trimmedName.split("/"); if (parts.length !== 2) { issues.push("Scoped package names must be in the format @scope/name"); } else if (parts[1].length === 0) { issues.push("Scoped package name cannot have empty package name"); } } return { valid: issues.length === 0, issues, }; } /** * Check if directory is available for project creation */ export function validateDirectoryAvailability(projectPath) { const issues = []; try { // Check if path exists if (fs.existsSync(projectPath)) { const stats = fs.statSync(projectPath); if (!stats.isDirectory()) { issues.push(`Path exists but is not a directory: ${projectPath}`); } else { // Check if directory is empty const files = fs.readdirSync(projectPath); const nonHiddenFiles = files.filter((file) => !file.startsWith(".")); if (nonHiddenFiles.length > 0) { issues.push(`Directory is not empty: ${projectPath}`); } } } // Check if parent directory is writable const parentDir = path.dirname(projectPath); try { fs.accessSync(parentDir, fs.constants.W_OK); } catch { issues.push(`Parent directory is not writable: ${parentDir}`); } } catch (error) { issues.push(`Error checking directory: ${error instanceof Error ? error.message : String(error)}`); } return { valid: issues.length === 0, issues, }; } //# sourceMappingURL=validate-project-name.js.map