mirror of
https://git.bits.team/Bits/mod-manager.git
synced 2024-11-21 21:48:21 -05:00
Ran a reformat
This commit is contained in:
parent
7d6d49ec19
commit
d47e752f1a
@ -1,8 +1,11 @@
|
|||||||
# Mod Manager
|
# Mod Manager
|
||||||
|
|
||||||
A package manager-like CLI utility for installing, upgrading and migrating mods on Fabric Minecraft Servers
|
A package manager-like CLI utility for installing, upgrading and migrating mods on Fabric Minecraft Servers
|
||||||
|
|
||||||
## Envrionment Variables
|
## Envrionment Variables
|
||||||
|
|
||||||
The list of required variables are as follows:
|
The list of required variables are as follows:
|
||||||
|
|
||||||
```
|
```
|
||||||
CURSEFORGE_API_KEY="**api key goes here**"
|
CURSEFORGE_API_KEY="**api key goes here**"
|
||||||
```
|
```
|
@ -9,7 +9,7 @@ export default class InstallCommand implements Subcommand {
|
|||||||
.description("Installs the provided mods")
|
.description("Installs the provided mods")
|
||||||
.argument("<mods...>", "The mods to install")
|
.argument("<mods...>", "The mods to install")
|
||||||
.option("-e, --essential", "Marks these mods as essential", false)
|
.option("-e, --essential", "Marks these mods as essential", false)
|
||||||
.action(function() {
|
.action(function () {
|
||||||
ModManager.execute(async () => {
|
ModManager.execute(async () => {
|
||||||
for (const mod of this.args) {
|
for (const mod of this.args) {
|
||||||
await Mods.install(mod, this.opts().essential);
|
await Mods.install(mod, this.opts().essential);
|
||||||
|
@ -13,7 +13,7 @@ export class ListCommand implements Subcommand {
|
|||||||
.description("Lists installed mods")
|
.description("Lists installed mods")
|
||||||
.action(() => {
|
.action(() => {
|
||||||
ModManager.execute(() => {
|
ModManager.execute(() => {
|
||||||
const tableFunc = asTable.configure ({
|
const tableFunc = asTable.configure({
|
||||||
title: x => chalk.cyanBright(Util.stringPrettyify(x)),
|
title: x => chalk.cyanBright(Util.stringPrettyify(x)),
|
||||||
delimiter: chalk.blueBright(' | '),
|
delimiter: chalk.blueBright(' | '),
|
||||||
dash: chalk.blueBright('-')
|
dash: chalk.blueBright('-')
|
||||||
|
@ -8,7 +8,7 @@ export default class UpdateCommand implements Subcommand {
|
|||||||
program.command("update")
|
program.command("update")
|
||||||
.description("Checks for and updates mods that have a newer available version")
|
.description("Checks for and updates mods that have a newer available version")
|
||||||
.action(() => {
|
.action(() => {
|
||||||
ModManager.execute(async() => {
|
ModManager.execute(async () => {
|
||||||
await Mods.update();
|
await Mods.update();
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -20,9 +20,15 @@ import {CurseforgeSource} from "./mods/sources/curseforge_source.js";
|
|||||||
|
|
||||||
export default class ModManager {
|
export default class ModManager {
|
||||||
public static logger: Logger | null = null;
|
public static logger: Logger | null = null;
|
||||||
|
static FilePaths = class {
|
||||||
|
public static readonly MOD_MANAGER_FOLDER_PATH = path.join(".mod-manager");
|
||||||
|
public static readonly LOGS_FOLDER = path.join(this.MOD_MANAGER_FOLDER_PATH, "logs");
|
||||||
|
public static readonly LOG_FILE: string = path.join(this.LOGS_FOLDER, `${new Date().valueOf()}.log.json`);
|
||||||
|
public static readonly MOD_FILE_PATH = path.join(this.MOD_MANAGER_FOLDER_PATH, "mods.json");
|
||||||
|
public static readonly VERSION_FILE_PATH = path.join(this.MOD_MANAGER_FOLDER_PATH, "version")
|
||||||
|
public static readonly MODS_FOLDER_PATH = path.join("mods")
|
||||||
|
}
|
||||||
private static program: Command = new Command();
|
private static program: Command = new Command();
|
||||||
|
|
||||||
private static subcommands: Array<Subcommand> = [
|
private static subcommands: Array<Subcommand> = [
|
||||||
new InitCommand(),
|
new InitCommand(),
|
||||||
new InstallCommand(),
|
new InstallCommand(),
|
||||||
@ -34,15 +40,6 @@ export default class ModManager {
|
|||||||
new MigrateCommand()
|
new MigrateCommand()
|
||||||
];
|
];
|
||||||
|
|
||||||
static FilePaths = class {
|
|
||||||
public static readonly MOD_MANAGER_FOLDER_PATH = path.join(".mod-manager");
|
|
||||||
public static readonly LOGS_FOLDER = path.join(this.MOD_MANAGER_FOLDER_PATH, "logs");
|
|
||||||
public static readonly LOG_FILE: string = path.join(this.LOGS_FOLDER, `${new Date().valueOf()}.log.json`);
|
|
||||||
public static readonly MOD_FILE_PATH = path.join(this.MOD_MANAGER_FOLDER_PATH, "mods.json");
|
|
||||||
public static readonly VERSION_FILE_PATH = path.join(this.MOD_MANAGER_FOLDER_PATH, "version")
|
|
||||||
public static readonly MODS_FOLDER_PATH = path.join("mods")
|
|
||||||
}
|
|
||||||
|
|
||||||
static init() {
|
static init() {
|
||||||
if (Initialiser.isInitialised()) {
|
if (Initialiser.isInitialised()) {
|
||||||
this.logger = ModManager.createLogger();
|
this.logger = ModManager.createLogger();
|
||||||
@ -74,10 +71,11 @@ export default class ModManager {
|
|||||||
|
|
||||||
static createLogger(): Logger {
|
static createLogger(): Logger {
|
||||||
let logger = pino({
|
let logger = pino({
|
||||||
base: {
|
base: {
|
||||||
pid: undefined,
|
pid: undefined,
|
||||||
hostname: undefined}
|
hostname: undefined
|
||||||
},
|
}
|
||||||
|
},
|
||||||
pino.destination({
|
pino.destination({
|
||||||
dest: ModManager.FilePaths.LOG_FILE,
|
dest: ModManager.FilePaths.LOG_FILE,
|
||||||
sync: true
|
sync: true
|
||||||
|
@ -107,12 +107,12 @@ export default class Mods {
|
|||||||
this.silentUninstall(modToUninstall);
|
this.silentUninstall(modToUninstall);
|
||||||
|
|
||||||
for (let dependency of modToUninstall.dependencies) {
|
for (let dependency of modToUninstall.dependencies) {
|
||||||
if (!this.isDependedOn(dependency)) {
|
if (!this.isDependedOn(dependency)) {
|
||||||
const dependencyMod = this.findMod(dependency);
|
const dependencyMod = this.findMod(dependency);
|
||||||
if (dependencyMod != undefined) {
|
if (dependencyMod != undefined) {
|
||||||
this.silentUninstall(dependencyMod)
|
this.silentUninstall(dependencyMod)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
spinner.succeed(`${modToUninstall.name} successfully uninstalled!`)
|
spinner.succeed(`${modToUninstall.name} successfully uninstalled!`)
|
||||||
@ -161,30 +161,6 @@ export default class Mods {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds the mod based on the provided id or name
|
|
||||||
* @param mod the id or mod name
|
|
||||||
* @return the found Mod, or undefined if no mod was found
|
|
||||||
*/
|
|
||||||
private static findMod(mod: string): TrackedMod | undefined {
|
|
||||||
// Replace underscores and dashes with spaces
|
|
||||||
mod = mod.replaceAll("_", " ");
|
|
||||||
mod = mod.replaceAll("-", " ")
|
|
||||||
|
|
||||||
let mods: Array<TrackedMod> = this.getTrackedMods();
|
|
||||||
for (let modEle of mods) {
|
|
||||||
const id = modEle.id.toLowerCase();
|
|
||||||
const name = modEle.name.toLowerCase();
|
|
||||||
|
|
||||||
const query = mod.toLowerCase();
|
|
||||||
if (id == query || Util.areStringsSimilar(mod, name)) {
|
|
||||||
return modEle;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
static async update() {
|
static async update() {
|
||||||
const trackedMods = this.getTrackedMods();
|
const trackedMods = this.getTrackedMods();
|
||||||
|
|
||||||
@ -202,7 +178,7 @@ export default class Mods {
|
|||||||
|
|
||||||
// Get the latest version
|
// Get the latest version
|
||||||
const source = this.getSourceFromName(mod.source);
|
const source = this.getSourceFromName(mod.source);
|
||||||
let latestVersion: Version | undefined = undefined;
|
let latestVersion: Version | undefined = undefined;
|
||||||
try {
|
try {
|
||||||
latestVersion = await source.getLatestVersion(mod.id, mcVersion);
|
latestVersion = await source.getLatestVersion(mod.id, mcVersion);
|
||||||
|
|
||||||
@ -286,10 +262,6 @@ export default class Mods {
|
|||||||
return possible;
|
return possible;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static getEssentialMods() {
|
|
||||||
return this.getTrackedMods().filter(mod => mod.essential);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Migrates to the provided version of minecraft
|
* Migrates to the provided version of minecraft
|
||||||
* @param version the Minecraft version to migrate to
|
* @param version the Minecraft version to migrate to
|
||||||
@ -343,6 +315,34 @@ export default class Mods {
|
|||||||
PrintUtils.success(`Successfully migrated to ${version}`)
|
PrintUtils.success(`Successfully migrated to ${version}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Finds the mod based on the provided id or name
|
||||||
|
* @param mod the id or mod name
|
||||||
|
* @return the found Mod, or undefined if no mod was found
|
||||||
|
*/
|
||||||
|
private static findMod(mod: string): TrackedMod | undefined {
|
||||||
|
// Replace underscores and dashes with spaces
|
||||||
|
mod = mod.replaceAll("_", " ");
|
||||||
|
mod = mod.replaceAll("-", " ")
|
||||||
|
|
||||||
|
let mods: Array<TrackedMod> = this.getTrackedMods();
|
||||||
|
for (let modEle of mods) {
|
||||||
|
const id = modEle.id.toLowerCase();
|
||||||
|
const name = modEle.name.toLowerCase();
|
||||||
|
|
||||||
|
const query = mod.toLowerCase();
|
||||||
|
if (id == query || Util.areStringsSimilar(mod, name)) {
|
||||||
|
return modEle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static getEssentialMods() {
|
||||||
|
return this.getTrackedMods().filter(mod => mod.essential);
|
||||||
|
}
|
||||||
|
|
||||||
private static isDependedOn(dependency: string) {
|
private static isDependedOn(dependency: string) {
|
||||||
const trackedMods = this.getTrackedMods();
|
const trackedMods = this.getTrackedMods();
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { stringSimilarity } from "string-similarity-js";
|
import {stringSimilarity} from "string-similarity-js";
|
||||||
|
|
||||||
export default class Util {
|
export default class Util {
|
||||||
private static readonly SIMILARITY_THRESHOLD: number = 0.8;
|
private static readonly SIMILARITY_THRESHOLD: number = 0.8;
|
||||||
@ -11,7 +11,9 @@ export default class Util {
|
|||||||
return str // insert a space before all caps
|
return str // insert a space before all caps
|
||||||
.replace(/([A-Z])/g, ' $1')
|
.replace(/([A-Z])/g, ' $1')
|
||||||
// uppercase the first character
|
// uppercase the first character
|
||||||
.replace(/^./, function(str){ return str.toUpperCase(); })
|
.replace(/^./, function (str) {
|
||||||
|
return str.toUpperCase();
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
static areStringsSimilar(master: string, compare: string): boolean {
|
static areStringsSimilar(master: string, compare: string): boolean {
|
||||||
|
@ -4,34 +4,53 @@
|
|||||||
"lib": [
|
"lib": [
|
||||||
"ESNext",
|
"ESNext",
|
||||||
"dom"
|
"dom"
|
||||||
], // specifies which default set of type definitions to use ("DOM", "ES6", etc)
|
],
|
||||||
"outDir": "dist", // .js (as well as .d.ts, .js.map, etc.) files will be emitted into this directory.,
|
// specifies which default set of type definitions to use ("DOM", "ES6", etc)
|
||||||
"removeComments": true, // Strips all comments from TypeScript files when converting into JavaScript- you rarely read compiled code so this saves space
|
"outDir": "dist",
|
||||||
"target": "ES6", // Target environment. Most modern browsers support ES6, but you may want to set it to newer or older. (defaults to ES3)
|
// .js (as well as .d.ts, .js.map, etc.) files will be emitted into this directory.,
|
||||||
|
"removeComments": true,
|
||||||
|
// Strips all comments from TypeScript files when converting into JavaScript- you rarely read compiled code so this saves space
|
||||||
|
"target": "ES6",
|
||||||
|
// Target environment. Most modern browsers support ES6, but you may want to set it to newer or older. (defaults to ES3)
|
||||||
|
|
||||||
// Module resolution
|
// Module resolution
|
||||||
"baseUrl": "./", // Lets you set a base directory to resolve non-absolute module names.
|
"baseUrl": "./",
|
||||||
"esModuleInterop": true, // fixes some issues TS originally had with the ES6 spec where TypeScript treats CommonJS/AMD/UMD modules similar to ES6 module
|
// Lets you set a base directory to resolve non-absolute module names.
|
||||||
"moduleResolution": "node", // Pretty much always node for modern JS. Other option is "classic"
|
"esModuleInterop": true,
|
||||||
"paths": {}, // A series of entries which re-map imports to lookup locations relative to the baseUrl
|
// fixes some issues TS originally had with the ES6 spec where TypeScript treats CommonJS/AMD/UMD modules similar to ES6 module
|
||||||
|
"moduleResolution": "node",
|
||||||
|
// Pretty much always node for modern JS. Other option is "classic"
|
||||||
|
"paths": {},
|
||||||
|
// A series of entries which re-map imports to lookup locations relative to the baseUrl
|
||||||
|
|
||||||
// Source Map
|
// Source Map
|
||||||
"sourceMap": true, // enables the use of source maps for debuggers and error reporting etc
|
"sourceMap": true,
|
||||||
"sourceRoot": "/", // Specify the location where a debugger should locate TypeScript files instead of relative source locations.
|
// enables the use of source maps for debuggers and error reporting etc
|
||||||
|
"sourceRoot": "/",
|
||||||
|
// Specify the location where a debugger should locate TypeScript files instead of relative source locations.
|
||||||
|
|
||||||
// Strict Checks
|
// Strict Checks
|
||||||
"alwaysStrict": true, // Ensures that your files are parsed in the ECMAScript strict mode, and emit “use strict” for each source file.
|
"alwaysStrict": true,
|
||||||
"allowUnreachableCode": false, // pick up dead code paths
|
// Ensures that your files are parsed in the ECMAScript strict mode, and emit “use strict” for each source file.
|
||||||
"noImplicitAny": true, // In some cases where no type annotations are present, TypeScript will fall back to a type of any for a variable when it cannot infer the type.
|
"allowUnreachableCode": false,
|
||||||
"strictNullChecks": true, // When strictNullChecks is true, null and undefined have their own distinct types and you’ll get a type error if you try to use them where a concrete value is expected.
|
// pick up dead code paths
|
||||||
|
"noImplicitAny": true,
|
||||||
|
// In some cases where no type annotations are present, TypeScript will fall back to a type of any for a variable when it cannot infer the type.
|
||||||
|
"strictNullChecks": true,
|
||||||
|
// When strictNullChecks is true, null and undefined have their own distinct types and you’ll get a type error if you try to use them where a concrete value is expected.
|
||||||
|
|
||||||
// Linter Checks
|
// Linter Checks
|
||||||
"noImplicitReturns": true,
|
"noImplicitReturns": true,
|
||||||
"noUncheckedIndexedAccess": true, // accessing index must always check for undefined
|
"noUncheckedIndexedAccess": true,
|
||||||
"noUnusedLocals": true, // Report errors on unused local variables.
|
// accessing index must always check for undefined
|
||||||
"noUnusedParameters": true // Report errors on unused parameters in functions
|
"noUnusedLocals": true,
|
||||||
|
// Report errors on unused local variables.
|
||||||
|
"noUnusedParameters": true
|
||||||
|
// Report errors on unused parameters in functions
|
||||||
},
|
},
|
||||||
"include": ["./**/*.ts"],
|
"include": [
|
||||||
|
"./**/*.ts"
|
||||||
|
],
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"node_modules/**/*"
|
"node_modules/**/*"
|
||||||
]
|
]
|
||||||
|
Loading…
Reference in New Issue
Block a user