From 6d195aee1ce2c06dedb0a72fe1c35b4f85f48d22 Mon Sep 17 00:00:00 2001 From: Michael Ochmann Date: Wed, 2 Nov 2022 23:58:59 +0100 Subject: [PATCH] initial commit --- .env.sample | 0 .gitignore | 6 +++++ main.js | 17 +++++++++++++ package-lock.json | 23 +++++++++++++++++ package.json | 22 +++++++++++++++++ src/EternalTypes.js | 12 +++++++++ src/MPT.js | 38 ++++++++++++++++++++++++++++ src/search.js | 33 +++++++++++++++++++++++++ src/util.js | 60 +++++++++++++++++++++++++++++++++++++++++++++ 9 files changed, 211 insertions(+) create mode 100644 .env.sample create mode 100644 .gitignore create mode 100644 main.js create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 src/EternalTypes.js create mode 100644 src/MPT.js create mode 100644 src/search.js create mode 100644 src/util.js diff --git a/.env.sample b/.env.sample new file mode 100644 index 0000000..e69de29 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e1be268 --- /dev/null +++ b/.gitignore @@ -0,0 +1,6 @@ +.idea +.vscode +.DS_Store + +node_modules +.env diff --git a/main.js b/main.js new file mode 100644 index 0000000..ee1f4b8 --- /dev/null +++ b/main.js @@ -0,0 +1,17 @@ +"use strict"; + +import dotenv from "dotenv"; +import MPT from "./src/MPT.js"; +import getopts from "getopts"; +import Curseforge from "node-curseforge"; + +dotenv.config(); + +const cliOptions = getopts(process.argv.slice(2), { + stopEarly : true, + string : ["v"] +}); +console.log(cliOptions); + +const APP = new MPT(cliOptions); + diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..8aab18d --- /dev/null +++ b/package-lock.json @@ -0,0 +1,23 @@ +{ + "name": "mpt", + "version": "0.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "dotenv": { + "version": "16.0.3", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.0.3.tgz", + "integrity": "sha512-7GO6HghkA5fYG9TYnNxi14/7K9f5occMlp3zXAuSxn7CKCxt9xbNWG7yF8hTCSUchlfWSe3uLmlPfigevRItzQ==" + }, + "getopts": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/getopts/-/getopts-2.3.0.tgz", + "integrity": "sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA==" + }, + "node-curseforge": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/node-curseforge/-/node-curseforge-1.2.2.tgz", + "integrity": "sha512-dfvKVN7pup3we+yFLzrpWG+o20t+XhMMnIVfNBCQ513TnNI93TrMsCXjNPMLCEBB5DFSAnXGdrKwqRQrB18Qeg==" + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..e71b09b --- /dev/null +++ b/package.json @@ -0,0 +1,22 @@ +{ + "name": "mpt", + "version": "0.0.1", + "description": "a package manager for curseforge plugins for minecraft", + "main": "main.js", + "scripts": { + "start": "node ." + }, + "type": "module", + "keywords": [ + "minecraft", + "fabric", + "curseforge" + ], + "author": "MikO ", + "license": "MIT", + "dependencies": { + "dotenv": "^16.0.3", + "getopts": "^2.3.0", + "node-curseforge": "^1.2.2" + } +} diff --git a/src/EternalTypes.js b/src/EternalTypes.js new file mode 100644 index 0000000..226558d --- /dev/null +++ b/src/EternalTypes.js @@ -0,0 +1,12 @@ +const ModLoaderType = Object.freeze({ + ANY : 0, + FORGE : 1, + CAULDRON : 2, + LITELOADER : 3, + FABRIC : 4, + QUILT : 5 +}); + +export { + ModLoaderType +} \ No newline at end of file diff --git a/src/MPT.js b/src/MPT.js new file mode 100644 index 0000000..efd905e --- /dev/null +++ b/src/MPT.js @@ -0,0 +1,38 @@ +import {message, error, log, debug, Color, _} from "./util.js"; +import search from "./search.js"; + +class MPT { + options; + subcommand; + + constructor(options) { + this.options = options; + + const subcommand = options._[0]; + const parameters = options._.slice(1); + switch(subcommand) { + case "search": + this.search(parameters, options.v === "" ? null : options.v); + break; + default: + message(`unknown command '${subcommand}'`); + break; + } + } + + async search(parameters, version = null) { + if (!parameters) + error(" You must give at least one search pattern"); + const results = await search(parameters.join(" "), version); + for(const result of results) { + log(`${_(Color.GREEN)}${result.name} ${_(Color.MAGENTA)}[${result.id}]${_(Color.NONE)}`); + log(` ${result.description}\n`); + log(` ${_(Color.CYAN)}latest files:`); + for (const file of result.files) + log(` ${_(Color.CYAN)}- ${_(Color.YELLOW)}${file}${_(Color.NONE)}`); + } + } + +} + +export default MPT; \ No newline at end of file diff --git a/src/search.js b/src/search.js new file mode 100644 index 0000000..5d40a7f --- /dev/null +++ b/src/search.js @@ -0,0 +1,33 @@ + +import {curseforge, debug} from "./util.js"; +import {ModLoaderType} from "./EternalTypes.js"; + +const search = async (pattern, version = null) => { + const minecraft = await curseforge().get_game("minecraft"); + + const filter = {searchFilter : pattern, modLoaderType : ModLoaderType.FABRIC, pageSize : 2, sortField : 5}; + if (version) + filter.version = version; + const mods = await minecraft.search_mods(filter); + const result = []; + + for (const mod of mods) { + const filter = {modLoaderType: ModLoaderType.FABRIC, pageSize : 3}; + if (version) + filter.version = version; + const files = await mod.get_files(filter); + + result.push({ + id : mod.id, + name : mod.name, + description : mod.summary, + files : files.map(file => file.fileName) + }); + } + + + return result; +}; + + +export default search; \ No newline at end of file diff --git a/src/util.js b/src/util.js new file mode 100644 index 0000000..6ae9e77 --- /dev/null +++ b/src/util.js @@ -0,0 +1,60 @@ +import util from "util"; +import CurseForge from "node-curseforge"; + +const Color = Object.freeze({ // these are magic numbers for ANSI escape sequences and go here: \u001B[m + NONE : 0, + RED : 31, + BLACK : 30, + GREEN : 32, + YELLOW : 33, + BLUE : 34, + MAGENTA : 35, + CYAN : 36, + WHITE : 37, + BLACKBRIGHT : 90, + REDBRIGHT : 91, + GREENBRIGHT : 92, + YELLOWBRIGHT : 93, + BLUEBRIGHT : 94, + MAGENTABRIGHT : 95, + CYANBRIGHT : 96, + WHITEBRIGHT : 97 +}); + +const _ = color => { + return `\u001B[${color}m`; +}; + +const log = console["log"]; + +let CF = null; + +const message = string => { + log(`mpt: ${string}`) +}; + +const error = string => { + message(`ERROR: ${string}`); + process.exit(0); +}; + +const debug = data => { + console.log(util.inspect(data, {showHidden: false, depth: null, colors: true})); +}; + +const curseforge = () => { + if (!CF) + CF = new CurseForge.default(process.env.ETERNAL_API_KEY); + + return CF; +}; + +export { + message, + error, + debug, + log, + Color, + curseforge, + _ +}; \ No newline at end of file