UNPKG

nmdk

Version:

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

148 lines (117 loc) 4.96 kB
const axios = require('axios'); const path = require('path'); const fs = require('fs-extra'); const { downloadFileFromUrl } = require('../utils/download'); const { extractProjectArchive, reorganizeProjectStructure } = require('../utils/extract'); const { sanitizeGradleConfigurationFiles, configureFabricModMetadata, executeGradleBuildCommands } = require('../utils/gradle'); const ora = require('ora'); const chalk = require('chalk'); async function resolveFabricMDKDownloadUrl(mcVersion, fabricVersion) { const spinner = ora('Resolving Fabric MDK download URL').start(); try { try { const response = await axios.get(`https://api.github.com/repos/FabricMC/fabric-example-mod/releases/latest`); const release = response.data; const mdkAsset = release.assets.find(asset => asset.name.includes('mdk') && asset.name.includes(mcVersion) ); if (mdkAsset) { spinner.succeed(chalk.green('Fabric MDK URL resolved from GitHub')); return mdkAsset.browser_download_url; } } catch (githubError) { } const baseUrl = 'https://github.com/FabricMC/fabric-example-mod/archive/refs/heads/'; const branchName = `${mcVersion}.x`; const directUrl = `${baseUrl}${branchName}.zip`; try { const response = await axios.head(directUrl); if (response.status === 200) { spinner.succeed(chalk.green('Fabric MDK URL resolved from direct link')); return directUrl; } } catch (directError) { const alternativeBranches = [ `${mcVersion}`, `1.${mcVersion.split('.')[1]}.x`, 'main', 'master' ]; for (const branch of alternativeBranches) { const altUrl = `${baseUrl}${branch}.zip`; try { const altResponse = await axios.head(altUrl); if (altResponse.status === 200) { spinner.succeed(chalk.green(`Fabric MDK URL resolved from branch: ${branch}`)); return altUrl; } } catch (altError) { continue; } } } throw new Error(`No Fabric MDK found for MC ${mcVersion}`); } catch (error) { spinner.fail('Failed to get Fabric MDK URL'); throw new Error(`Failed to get Fabric MDK URL: ${error.message}`); } } async function initializeFabricProject(modName, mcVersion, fabricVersion, projectPath, modConfig) { const spinner = ora('Initializing Fabric project').start(); try { const mdkUrl = await resolveFabricMDKDownloadUrl(mcVersion, fabricVersion); const archivePath = path.join(projectPath, 'fabric-mdk.zip'); await downloadFileFromUrl(mdkUrl, archivePath); const tempExtractPath = path.join(projectPath, 'temp-extract'); await extractProjectArchive(archivePath, tempExtractPath); await reorganizeProjectStructure(tempExtractPath, projectPath); try { await fs.remove(tempExtractPath); } catch (error) { console.warn('Warning: Could not remove temp extract directory:', error.message); } try { await fs.remove(archivePath); } catch (error) { console.warn('Warning: Could not remove archive file:', error.message); } await sanitizeGradleConfigurationFiles(projectPath); await configureFabricModMetadata(projectPath, modConfig); await configureFabricModJsonFile(projectPath, modConfig, mcVersion, fabricVersion); spinner.succeed(chalk.green('Fabric project initialized')); } catch (error) { spinner.fail('Failed to setup Fabric project'); throw new Error(`Failed to setup Fabric project: ${error.message}`); } } async function configureFabricModJsonFile(projectPath, modConfig, mcVersion, fabricVersion) { const fabricModJsonPath = path.join(projectPath, 'src/main/resources/fabric.mod.json'); if (await fs.pathExists(fabricModJsonPath)) { let content = await fs.readFile(fabricModJsonPath, 'utf8'); const fabricMod = JSON.parse(content); fabricMod.id = modConfig.modId; fabricMod.name = modConfig.modName; fabricMod.description = modConfig.description; fabricMod.version = modConfig.version; fabricMod.authors = [modConfig.author]; fabricMod.depends = { "fabricloader": `>=${fabricVersion}`, "minecraft": `~${mcVersion}`, "java": ">=17" }; await fs.writeFile(fabricModJsonPath, JSON.stringify(fabricMod, null, 2)); } } async function executeFabricGradleCommands(projectPath, options = []) { const commands = []; if (options.includes('build')) { commands.push('./gradlew build'); } if (commands.length > 0) { await executeGradleBuildCommands(projectPath, commands); } } module.exports = { initializeFabricProject, executeFabricGradleCommands };