UNPKG

nmdk

Version:

CLI tool for downloading and setting up Minecraft mod development kits (MDK) for Forge, Fabric, and NeoForge

118 lines (98 loc) 5.93 kB
const fs = require('fs-extra'); const path = require('path'); const chalk = require('chalk'); const { retrieveLatestLoaderVersion } = require('./utils/download'); const { collectModConfigurationData, requestProjectCreationConfirmation } = require('./utils/prompts'); const { initializeForgeProject } = require('./loaders/forge'); const { initializeFabricProject } = require('./loaders/fabric'); const { initializeNeoForgeProject } = require('./loaders/neoforge'); async function initializeModProject(modName, mcVersion, loader, loaderVersion) { try { displayProjectInitializationHeader(modName, mcVersion, loader, loaderVersion); validateProjectParameters(modName, mcVersion, loader, loaderVersion); const projectPath = path.resolve(modName); if (await fs.pathExists(projectPath)) { throw new Error(`Directory ${modName} already exists`); } let actualLoaderVersion = loaderVersion; if (loaderVersion === 'latest') { actualLoaderVersion = await retrieveLatestLoaderVersion(loader, mcVersion); } const modConfig = await collectModConfigurationData(modName); const confirmed = await requestProjectCreationConfirmation(modConfig); if (!confirmed) { console.log(chalk.yellow('Project creation cancelled')); return; } await fs.ensureDir(projectPath); await configureProjectByLoader(loader, modName, mcVersion, actualLoaderVersion, projectPath, modConfig); displayProjectCompletionSummary(modName, loader, mcVersion, actualLoaderVersion); } catch (error) { throw new Error(`Failed to create project: ${error.message}`); } } function validateProjectParameters(modName, mcVersion, loader, loaderVersion) { if (!modName || modName.trim().length === 0) { throw new Error('Mod name cannot be empty'); } if (!mcVersion || !/^\d+\.\d+(\.\d+)?$/.test(mcVersion)) { throw new Error('Minecraft version must be in format X.Y or X.Y.Z'); } const validLoaders = ['forge', 'fabric', 'neoforge']; if (!validLoaders.includes(loader.toLowerCase())) { throw new Error(`Invalid loader. Must be one of: ${validLoaders.join(', ')}`); } if (loader.toLowerCase() === 'neoforge') { const versionParts = mcVersion.split('.').map(Number); const major = versionParts[0]; const minor = versionParts[1] || 0; const patch = versionParts[2] || 0; if (major < 1 || (major === 1 && minor < 20) || (major === 1 && minor === 20 && patch < 1)) { throw new Error('NeoForge only supports Minecraft 1.20.1 and above'); } } } async function configureProjectByLoader(loader, modName, mcVersion, loaderVersion, projectPath, modConfig) { switch (loader.toLowerCase()) { case 'forge': await initializeForgeProject(modName, mcVersion, loaderVersion, projectPath, modConfig); break; case 'fabric': await initializeFabricProject(modName, mcVersion, loaderVersion, projectPath, modConfig); break; case 'neoforge': await initializeNeoForgeProject(modName, mcVersion, loaderVersion, projectPath, modConfig); break; default: throw new Error(`Unsupported loader: ${loader}`); } } function displayProjectCompletionSummary(modName, loader, mcVersion, loaderVersion) { console.log(chalk.blue.bold('='.repeat(75))); console.log(chalk.green('Project created successfully!')); console.log(chalk.blue.bold('='.repeat(75))); console.log(chalk.blue('\nProject Information:')); console.log(chalk.gray('─'.repeat(40))); console.log(chalk.white(` Mod Name: ${chalk.cyan(modName)}`)); console.log(chalk.white(` Loader: ${chalk.cyan(loader)} ${chalk.yellow(loaderVersion)}`)); console.log(chalk.white(` Minecraft: ${chalk.cyan(mcVersion)}`)); console.log(chalk.white(` Directory: ${chalk.gray(path.resolve(modName))}`)); console.log(chalk.gray('─'.repeat(40))); console.log(chalk.blue.bold('='.repeat(75))); } function displayProjectInitializationHeader(modName, mcVersion, loader, loaderVersion) { console.clear(); console.log(chalk.green.bold('███╗ ███╗██████╗ ██╗ ██╗██╗ ██╗███████╗██╗ ██████╗ ███████╗██████╗ ')); console.log(chalk.green.bold('████╗ ████║██╔══██╗██║ ██╔╝██║ ██║██╔════╝██║ ██╔══██╗██╔════╝██╔══██╗')); console.log(chalk.green.bold('██╔████╔██║██║ ██║█████╔╝ ███████║█████╗ ██║ ██████╔╝█████╗ ██████╔╝')); console.log(chalk.green.bold('██║╚██╔╝██║██║ ██║██╔═██╗ ██╔══██║██╔══╝ ██║ ██╔═══╝ ██╔══╝ ██╔══██╗')); console.log(chalk.green.bold('██║ ╚═╝ ██║██████╔╝██║ ██╗██║ ██║███████╗███████╗██║ ███████╗██║ ██║')); console.log(chalk.green.bold('╚═╝ ╚═╝╚═════╝ ╚═╝ ╚═╝╚═╝ ╚═╝╚══════╝╚══════╝╚═╝ ╚══════╝╚═╝ ╚═╝')); console.log(chalk.blue.bold(`Project: ${chalk.cyan(modName)}`)); console.log(chalk.blue.bold(`Loader: ${chalk.cyan(loader)} ${chalk.yellow(loaderVersion)}`)); console.log(chalk.blue.bold(`Version: ${chalk.cyan(mcVersion)}`)); console.log(chalk.blue.bold('='.repeat(75))); } module.exports = { initializeModProject };