Files

47 lines
2.5 KiB
JavaScript

// Adds a Modrinth mod (and its required dependencies, recursively) to this packwiz pack.
// node tools/add-mod.mjs <slug-or-id> [...] → latest NeoForge 1.21.1 version
// node tools/add-mod.mjs <slug>@<version_number> → that exact version
// Writes mods/<slug>.pw.toml, then run: node tools/reindex.mjs
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
const UA = { 'User-Agent': 'Pinecraft-CreateRP/add-mod' };
const api = p => fetch('https://api.modrinth.com/v2' + p, { headers: UA }).then(r => {
if (!r.ok) throw new Error(`${p}: HTTP ${r.status}`);
return r.json();
});
const q = s => JSON.stringify(s);
const existing = new Set(fs.readdirSync(path.join(root, 'mods')).filter(f => f.endsWith('.pw.toml')).map(f => {
const t = fs.readFileSync(path.join(root, 'mods', f), 'utf8');
return (t.match(/^mod-id = "([^"]+)"/m) || [])[1];
}).filter(Boolean));
const sideOf = p => p.server_side === 'unsupported' ? 'client' : p.client_side === 'unsupported' ? 'server' : 'both';
async function add(spec, depth = 0) {
const [ref, wanted] = spec.split('@');
const project = await api(`/project/${ref}`);
const pad = ' '.repeat(depth);
if (existing.has(project.id)) { console.log(`${pad}= ${project.title} — already in the pack`); return; }
const versions = await api(`/project/${project.id}/version?loaders=${encodeURIComponent('["neoforge"]')}&game_versions=${encodeURIComponent('["1.21.1"]')}`);
const v = wanted ? versions.find(x => x.version_number === wanted) : versions[0];
if (!v) throw new Error(`${project.title}: no NeoForge 1.21.1 version${wanted ? ' ' + wanted : ''}`);
const f = v.files.find(x => x.primary) || v.files[0];
const toml = [
`name = ${q(project.title)}`, `filename = ${q(f.filename)}`, `side = ${q(sideOf(project))}`, '',
'[download]', `url = ${q(f.url)}`, 'hash-format = "sha512"', `hash = ${q(f.hashes.sha512)}`, '',
'[update]', '[update.modrinth]', `mod-id = ${q(project.id)}`, `version = ${q(v.id)}`, ''
].join('\n');
fs.writeFileSync(path.join(root, 'mods', `${project.slug}.pw.toml`), toml);
existing.add(project.id);
console.log(`${pad}+ ${project.title} ${v.version_number} (${sideOf(project)})`);
for (const d of v.dependencies.filter(d => d.dependency_type === 'required' && d.project_id)) {
await add(d.project_id, depth + 1);
}
}
for (const spec of process.argv.slice(2)) await add(spec);