mirror of
https://git.bits.team/Bits/mod-manager.git
synced 2025-04-20 23:07:01 -04:00
Compare commits
4 Commits
59e9c6fd08
...
2bd38816ad
Author | SHA1 | Date | |
---|---|---|---|
|
2bd38816ad | ||
|
21691f37db | ||
|
f7649e2aeb | ||
|
2d1513366c |
@ -77,6 +77,6 @@ The following are the required environment variables for running Mod Manager
|
|||||||
Mod Manager can be installed with the following command (watch out for the sudo password prompt, it can be hard to spot)
|
Mod Manager can be installed with the following command (watch out for the sudo password prompt, it can be hard to spot)
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl https://hogwarts.bits.team/git/Bits/mod-manager/raw/branch/master/install.sh | sudo -E env "PATH=$PATH" bash
|
curl https://git.bits.team/Bits/mod-manager/raw/branch/master/install.sh | sudo -E env "PATH=$PATH" bash
|
||||||
```
|
```
|
||||||
|
|
@ -62,7 +62,7 @@ fi
|
|||||||
|
|
||||||
# Download source files
|
# Download source files
|
||||||
info "Downloading mod-manager source..."
|
info "Downloading mod-manager source..."
|
||||||
git clone "https://hogwarts.bits.team/git/Bits/mod-manager.git" "$DOWNLOAD_DIR" || exit
|
git clone "https://git.bits.team/Bits/mod-manager.git" "$DOWNLOAD_DIR" || exit
|
||||||
|
|
||||||
# Compile
|
# Compile
|
||||||
info "Compiling..."
|
info "Compiling..."
|
||||||
|
75
package-lock.json
generated
75
package-lock.json
generated
@ -10,6 +10,7 @@
|
|||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/inquirer": "^9.0.0",
|
"@types/inquirer": "^9.0.0",
|
||||||
|
"@types/properties-parser": "^0.3.3",
|
||||||
"as-table": "^1.0.55",
|
"as-table": "^1.0.55",
|
||||||
"axios": "^0.27.2",
|
"axios": "^0.27.2",
|
||||||
"chalk": "^5.0.1",
|
"chalk": "^5.0.1",
|
||||||
@ -18,13 +19,14 @@
|
|||||||
"node-downloader-helper": "^2.1.2",
|
"node-downloader-helper": "^2.1.2",
|
||||||
"ora": "^6.1.2",
|
"ora": "^6.1.2",
|
||||||
"pino": "^8.3.1",
|
"pino": "^8.3.1",
|
||||||
|
"properties-parser": "^0.6.0",
|
||||||
"string-format": "^2.0.0",
|
"string-format": "^2.0.0",
|
||||||
"string-similarity-js": "^2.1.4",
|
"string-similarity-js": "^2.1.4",
|
||||||
"typescript-string-operations": "^1.4.1"
|
"typescript-string-operations": "^1.4.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^18.6.3",
|
"@types/node": "^18.19.30",
|
||||||
"typescript": "^4.7.4"
|
"typescript": "^4.9.5"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/inquirer": {
|
"node_modules/@types/inquirer": {
|
||||||
@ -37,9 +39,20 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "18.6.3",
|
"version": "18.19.30",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.6.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.30.tgz",
|
||||||
"integrity": "sha512-6qKpDtoaYLM+5+AFChLhHermMQxc3TOEFIDzrZLPRGHPrLEwqFkkT5Kx3ju05g6X7uDPazz3jHbKPX0KzCjntg=="
|
"integrity": "sha512-453z1zPuJLVDbyahaa1sSD5C2sht6ZpHp5rgJNs+H8YGqhluCXcuOUmBYsAo0Tos0cHySJ3lVUGbGgLlqIkpyg==",
|
||||||
|
"dependencies": {
|
||||||
|
"undici-types": "~5.26.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@types/properties-parser": {
|
||||||
|
"version": "0.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/properties-parser/-/properties-parser-0.3.3.tgz",
|
||||||
|
"integrity": "sha512-VZhGpE+QQ2JNbaY4B4Y2iM/jdUsq3HO75uBKLk07VT6P2Kg1aifeYL6I3RosFniSdAb4PtuH5UaY8jXU7JeIYA==",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/through": {
|
"node_modules/@types/through": {
|
||||||
"version": "0.0.30",
|
"version": "0.0.30",
|
||||||
@ -617,6 +630,14 @@
|
|||||||
"resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.0.0.tgz",
|
||||||
"integrity": "sha512-+MmoAXoUX+VTHAlwns0h+kFUWFs/3FZy+ZuchkgjyOu3oioLAo2LB5aCfKPh2+P9O18i3m43tUEv3YqttSy0Ww=="
|
"integrity": "sha512-+MmoAXoUX+VTHAlwns0h+kFUWFs/3FZy+ZuchkgjyOu3oioLAo2LB5aCfKPh2+P9O18i3m43tUEv3YqttSy0Ww=="
|
||||||
},
|
},
|
||||||
|
"node_modules/properties-parser": {
|
||||||
|
"version": "0.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/properties-parser/-/properties-parser-0.6.0.tgz",
|
||||||
|
"integrity": "sha512-qvr2cSmoA0dln0MARAKwBzPkkXn7FqwX+RVVNpMdMJc7rt9mqO2cXwluxtux9fHrLhjnPFaQkS8BM0kFrTCnSw==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 0.3.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/quick-format-unescaped": {
|
"node_modules/quick-format-unescaped": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz",
|
||||||
@ -824,9 +845,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/typescript": {
|
"node_modules/typescript": {
|
||||||
"version": "4.7.4",
|
"version": "4.9.5",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
|
||||||
"integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==",
|
"integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
"bin": {
|
"bin": {
|
||||||
"tsc": "bin/tsc",
|
"tsc": "bin/tsc",
|
||||||
@ -841,6 +862,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/typescript-string-operations/-/typescript-string-operations-1.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/typescript-string-operations/-/typescript-string-operations-1.4.1.tgz",
|
||||||
"integrity": "sha512-c+q+Tb0hxeebohdT9KpGUAm5zwxhU8pHeNOeuLCGFMXKN0OrldoAxtufrGLR3xSPCXDA4A3IBCEdRNNscVqLQg=="
|
"integrity": "sha512-c+q+Tb0hxeebohdT9KpGUAm5zwxhU8pHeNOeuLCGFMXKN0OrldoAxtufrGLR3xSPCXDA4A3IBCEdRNNscVqLQg=="
|
||||||
},
|
},
|
||||||
|
"node_modules/undici-types": {
|
||||||
|
"version": "5.26.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||||
|
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
|
||||||
|
},
|
||||||
"node_modules/util-deprecate": {
|
"node_modules/util-deprecate": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
@ -882,9 +908,20 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@types/node": {
|
"@types/node": {
|
||||||
"version": "18.6.3",
|
"version": "18.19.30",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.6.3.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.30.tgz",
|
||||||
"integrity": "sha512-6qKpDtoaYLM+5+AFChLhHermMQxc3TOEFIDzrZLPRGHPrLEwqFkkT5Kx3ju05g6X7uDPazz3jHbKPX0KzCjntg=="
|
"integrity": "sha512-453z1zPuJLVDbyahaa1sSD5C2sht6ZpHp5rgJNs+H8YGqhluCXcuOUmBYsAo0Tos0cHySJ3lVUGbGgLlqIkpyg==",
|
||||||
|
"requires": {
|
||||||
|
"undici-types": "~5.26.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@types/properties-parser": {
|
||||||
|
"version": "0.3.3",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/properties-parser/-/properties-parser-0.3.3.tgz",
|
||||||
|
"integrity": "sha512-VZhGpE+QQ2JNbaY4B4Y2iM/jdUsq3HO75uBKLk07VT6P2Kg1aifeYL6I3RosFniSdAb4PtuH5UaY8jXU7JeIYA==",
|
||||||
|
"requires": {
|
||||||
|
"@types/node": "*"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"@types/through": {
|
"@types/through": {
|
||||||
"version": "0.0.30",
|
"version": "0.0.30",
|
||||||
@ -1267,6 +1304,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.0.0.tgz",
|
||||||
"integrity": "sha512-+MmoAXoUX+VTHAlwns0h+kFUWFs/3FZy+ZuchkgjyOu3oioLAo2LB5aCfKPh2+P9O18i3m43tUEv3YqttSy0Ww=="
|
"integrity": "sha512-+MmoAXoUX+VTHAlwns0h+kFUWFs/3FZy+ZuchkgjyOu3oioLAo2LB5aCfKPh2+P9O18i3m43tUEv3YqttSy0Ww=="
|
||||||
},
|
},
|
||||||
|
"properties-parser": {
|
||||||
|
"version": "0.6.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/properties-parser/-/properties-parser-0.6.0.tgz",
|
||||||
|
"integrity": "sha512-qvr2cSmoA0dln0MARAKwBzPkkXn7FqwX+RVVNpMdMJc7rt9mqO2cXwluxtux9fHrLhjnPFaQkS8BM0kFrTCnSw=="
|
||||||
|
},
|
||||||
"quick-format-unescaped": {
|
"quick-format-unescaped": {
|
||||||
"version": "4.0.4",
|
"version": "4.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz",
|
||||||
@ -1417,9 +1459,9 @@
|
|||||||
"integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA=="
|
"integrity": "sha512-yGSza74xk0UG8k+pLh5oeoYirvIiWo5t0/o3zHHAO2tRDiZcxWP7fywNlXhqb6/r6sWvwi+RsyQMWhVLe4BVuA=="
|
||||||
},
|
},
|
||||||
"typescript": {
|
"typescript": {
|
||||||
"version": "4.7.4",
|
"version": "4.9.5",
|
||||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.7.4.tgz",
|
"resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz",
|
||||||
"integrity": "sha512-C0WQT0gezHuw6AdY1M2jxUO83Rjf0HP7Sk1DtXj6j1EwkQNZrHAg2XPWlq62oqEhYvONq5pkC2Y9oPljWToLmQ==",
|
"integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"typescript-string-operations": {
|
"typescript-string-operations": {
|
||||||
@ -1427,6 +1469,11 @@
|
|||||||
"resolved": "https://registry.npmjs.org/typescript-string-operations/-/typescript-string-operations-1.4.1.tgz",
|
"resolved": "https://registry.npmjs.org/typescript-string-operations/-/typescript-string-operations-1.4.1.tgz",
|
||||||
"integrity": "sha512-c+q+Tb0hxeebohdT9KpGUAm5zwxhU8pHeNOeuLCGFMXKN0OrldoAxtufrGLR3xSPCXDA4A3IBCEdRNNscVqLQg=="
|
"integrity": "sha512-c+q+Tb0hxeebohdT9KpGUAm5zwxhU8pHeNOeuLCGFMXKN0OrldoAxtufrGLR3xSPCXDA4A3IBCEdRNNscVqLQg=="
|
||||||
},
|
},
|
||||||
|
"undici-types": {
|
||||||
|
"version": "5.26.5",
|
||||||
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
|
||||||
|
"integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA=="
|
||||||
|
},
|
||||||
"util-deprecate": {
|
"util-deprecate": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||||
|
10
package.json
10
package.json
@ -5,13 +5,16 @@
|
|||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"build": "npx tsc",
|
||||||
|
"dev": "node ./build/ts/mod-manager.js",
|
||||||
|
"debug": "npm run build && npm run dev test"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/inquirer": "^9.0.0",
|
"@types/inquirer": "^9.0.0",
|
||||||
|
"@types/properties-parser": "^0.3.3",
|
||||||
"as-table": "^1.0.55",
|
"as-table": "^1.0.55",
|
||||||
"axios": "^0.27.2",
|
"axios": "^0.27.2",
|
||||||
"chalk": "^5.0.1",
|
"chalk": "^5.0.1",
|
||||||
@ -20,12 +23,13 @@
|
|||||||
"node-downloader-helper": "^2.1.2",
|
"node-downloader-helper": "^2.1.2",
|
||||||
"ora": "^6.1.2",
|
"ora": "^6.1.2",
|
||||||
"pino": "^8.3.1",
|
"pino": "^8.3.1",
|
||||||
|
"properties-parser": "^0.6.0",
|
||||||
"string-format": "^2.0.0",
|
"string-format": "^2.0.0",
|
||||||
"string-similarity-js": "^2.1.4",
|
"string-similarity-js": "^2.1.4",
|
||||||
"typescript-string-operations": "^1.4.1"
|
"typescript-string-operations": "^1.4.1"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^18.6.3",
|
"@types/node": "^18.19.30",
|
||||||
"typescript": "^4.7.4"
|
"typescript": "^4.9.5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ import Mods from "./mods/mods.js";
|
|||||||
import {CurseforgeSource} from "./mods/sources/curseforge_source.js";
|
import {CurseforgeSource} from "./mods/sources/curseforge_source.js";
|
||||||
import MinecraftUtils from "./util/minecraft_utils.js";
|
import MinecraftUtils from "./util/minecraft_utils.js";
|
||||||
import chalk from "chalk";
|
import chalk from "chalk";
|
||||||
|
import ForgejoSource from "./mods/sources/forgejo_source.js";
|
||||||
|
|
||||||
export default class ModManager {
|
export default class ModManager {
|
||||||
public static logger: Logger | null = null;
|
public static logger: Logger | null = null;
|
||||||
@ -63,6 +64,7 @@ export default class ModManager {
|
|||||||
|
|
||||||
Mods.registerSource(new ModrinthSource())
|
Mods.registerSource(new ModrinthSource())
|
||||||
Mods.registerSource(new CurseforgeSource(), "CURSEFORGE_API_KEY")
|
Mods.registerSource(new CurseforgeSource(), "CURSEFORGE_API_KEY")
|
||||||
|
Mods.registerSource(new ForgejoSource(), "FORGEJO_API_KEY")
|
||||||
|
|
||||||
this.program.showSuggestionAfterError();
|
this.program.showSuggestionAfterError();
|
||||||
this.program.showHelpAfterError();
|
this.program.showHelpAfterError();
|
||||||
|
157
src/mods/sources/forgejo_source.ts
Normal file
157
src/mods/sources/forgejo_source.ts
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
import axios from "axios";
|
||||||
|
import ModSource from "./mod_source.js";
|
||||||
|
import Util from "../../util/util.js";
|
||||||
|
import { ForgejoFile, ForgejoFiles, ForgejoPackage as ForgejoSearchResponse } from "../../types/forgejo.js";
|
||||||
|
import { parse } from "properties-parser"
|
||||||
|
import ModNotFoundError from "../../errors/mod_not_found_error.js";
|
||||||
|
import MinecraftUtils from "../../util/minecraft_utils.js";
|
||||||
|
import { format } from "util";
|
||||||
|
import Mods from "../mods.js";
|
||||||
|
import FileDownloader from "../../io/file_downloder.js";
|
||||||
|
import DownloadError from "../../errors/download_error.js";
|
||||||
|
|
||||||
|
export default class ForgejoSource implements ModSource {
|
||||||
|
private static readonly BASE_URL: string = "https://git.bits.team/api/v1";
|
||||||
|
private static readonly SEARCH_URL: string = ForgejoSource.BASE_URL + "/packages/Bits"
|
||||||
|
private static readonly VERSION_URL: string = ForgejoSource.BASE_URL + "/repos/%s/%s/media/gradle.properties"
|
||||||
|
private static readonly REPO_URL: string = ForgejoSource.BASE_URL + "/repositories/%s"
|
||||||
|
private static readonly FILES_URL: string = ForgejoSource.BASE_URL + "/packages/%s/%s/%s/%s/files"
|
||||||
|
|
||||||
|
private async findPackage(query: string, mcVersion: string): Promise<{package: ForgejoSearchResponse, project_id: string} | undefined> {
|
||||||
|
let page = 1;
|
||||||
|
let pagesLeft = true;
|
||||||
|
while (pagesLeft) {
|
||||||
|
pagesLeft = false
|
||||||
|
|
||||||
|
const params = {
|
||||||
|
q: query,
|
||||||
|
page
|
||||||
|
}
|
||||||
|
const response: ForgejoSearchResponse[] = await this.makeRequest(ForgejoSource.SEARCH_URL, params);
|
||||||
|
|
||||||
|
for (const mod of response) {
|
||||||
|
const versionParams = {
|
||||||
|
ref: mod.version
|
||||||
|
}
|
||||||
|
|
||||||
|
const url = format(ForgejoSource.VERSION_URL, mod.owner.username, mod.repository.name)
|
||||||
|
|
||||||
|
const versionResponse = await this.makeRequest(url, versionParams).catch(_ => "");
|
||||||
|
const ver = parse(versionResponse)
|
||||||
|
|
||||||
|
if (ver["minecraft_version"] == mcVersion) {
|
||||||
|
return {
|
||||||
|
package: mod,
|
||||||
|
project_id: mod.repository.id.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!Util.isArrayEmpty(response)) {
|
||||||
|
pagesLeft = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
page++
|
||||||
|
}
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
async search(query: string = "BitsVanilla"): Promise<string> {
|
||||||
|
const mcVersion = await MinecraftUtils.getCurrentMinecraftVersion();
|
||||||
|
|
||||||
|
let mod = await this.findPackage(query, mcVersion);
|
||||||
|
|
||||||
|
if (!mod) {
|
||||||
|
throw new ModNotFoundError(`Mod ${query} could not be found on Forgejo`)
|
||||||
|
}
|
||||||
|
|
||||||
|
return mod.project_id;
|
||||||
|
}
|
||||||
|
async install(version: Version, essential: boolean): Promise<void> {
|
||||||
|
try {
|
||||||
|
if (Mods.isModInstalled(version.modId)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
await FileDownloader.downloadMod(version)
|
||||||
|
|
||||||
|
const mod = {
|
||||||
|
name: await this.getProjectName(version.modId),
|
||||||
|
id: version.modId,
|
||||||
|
fileName: version.fileName,
|
||||||
|
version: version.versionNumber,
|
||||||
|
source: this.getSourceName(),
|
||||||
|
essential: essential,
|
||||||
|
dependencies: []
|
||||||
|
}
|
||||||
|
|
||||||
|
Mods.trackMod(mod)
|
||||||
|
} catch (e) {
|
||||||
|
throw new DownloadError(`An error occured downloading mod with id ${version.modId} from ${this.getSourceName()}`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
getSourceName(): string {
|
||||||
|
return "Forgejo";
|
||||||
|
}
|
||||||
|
async getProjectName(id: string): Promise<string> {
|
||||||
|
const response = await this.makeRequest(format(ForgejoSource.REPO_URL, id))
|
||||||
|
return response.name;
|
||||||
|
}
|
||||||
|
async getLatestVersion(id: string = "34", mcVersion: string = "24w13a"): Promise<Version> {
|
||||||
|
const projectName = await this.getProjectName(id)
|
||||||
|
|
||||||
|
const mod = await this.findPackage(projectName, mcVersion)
|
||||||
|
|
||||||
|
if (!mod) {
|
||||||
|
throw new ModNotFoundError(`Mod with id ${id} has no available versions on ${this.getSourceName()} for Minecraft version ${mcVersion}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
let filesUrl = format(ForgejoSource.FILES_URL, mod.package.owner.username, mod.package.type, mod.package.name, mod.package.version)
|
||||||
|
|
||||||
|
let filesResponse: ForgejoFiles = await this.makeRequest(filesUrl);
|
||||||
|
|
||||||
|
if (Util.isArrayEmpty(filesResponse)) {
|
||||||
|
throw new ModNotFoundError(`Mod ${mod.package.name} has no files on Forgejo`)
|
||||||
|
}
|
||||||
|
|
||||||
|
let latestFile: ForgejoFile | undefined = undefined;
|
||||||
|
for (const file of filesResponse) {
|
||||||
|
if (file.name.endsWith(".jar")) {
|
||||||
|
latestFile = file
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!latestFile) {
|
||||||
|
throw new ModNotFoundError(`Mod ${mod.package.name} has no jar files on Forgejo`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const downloadUrl = mod.package.html_url + `/files/${latestFile.id}`
|
||||||
|
|
||||||
|
const version = {
|
||||||
|
modId: mod.project_id,
|
||||||
|
versionNumber: mod.package.version,
|
||||||
|
fileName: latestFile.name,
|
||||||
|
url: downloadUrl,
|
||||||
|
dependencies: [],
|
||||||
|
checksum: latestFile.sha1
|
||||||
|
}
|
||||||
|
|
||||||
|
return version
|
||||||
|
}
|
||||||
|
|
||||||
|
private async makeRequest(url: string, params?: object) {
|
||||||
|
if (process.env.FORGEJO_API_KEY == undefined) {
|
||||||
|
throw new Error("Attempted Forgejo api calls with undefined api key environment variable (FORGEJO_API_KEY)")
|
||||||
|
}
|
||||||
|
|
||||||
|
params = Object.assign({}, {"access_token": process.env.FORGEJO_API_KEY}, params)
|
||||||
|
|
||||||
|
const response = await axios.get(url, {
|
||||||
|
params
|
||||||
|
})
|
||||||
|
|
||||||
|
return await response.data;
|
||||||
|
}
|
||||||
|
}
|
165
src/types/forgejo.d.ts
vendored
Normal file
165
src/types/forgejo.d.ts
vendored
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
export interface ForgejoPackage {
|
||||||
|
id: number
|
||||||
|
owner: Owner
|
||||||
|
repository: Repository
|
||||||
|
creator: Creator
|
||||||
|
type: string
|
||||||
|
name: string
|
||||||
|
version: string
|
||||||
|
html_url: string
|
||||||
|
created_at: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Owner {
|
||||||
|
id: number
|
||||||
|
login: string
|
||||||
|
login_name: string
|
||||||
|
full_name: string
|
||||||
|
email: string
|
||||||
|
avatar_url: string
|
||||||
|
language: string
|
||||||
|
is_admin: boolean
|
||||||
|
last_login: string
|
||||||
|
created: string
|
||||||
|
restricted: boolean
|
||||||
|
active: boolean
|
||||||
|
prohibit_login: boolean
|
||||||
|
location: string
|
||||||
|
website: string
|
||||||
|
description: string
|
||||||
|
visibility: string
|
||||||
|
followers_count: number
|
||||||
|
following_count: number
|
||||||
|
starred_repos_count: number
|
||||||
|
username: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Repository {
|
||||||
|
id: number
|
||||||
|
owner: Owner2
|
||||||
|
name: string
|
||||||
|
full_name: string
|
||||||
|
description: string
|
||||||
|
empty: boolean
|
||||||
|
private: boolean
|
||||||
|
fork: boolean
|
||||||
|
template: boolean
|
||||||
|
parent: any
|
||||||
|
mirror: boolean
|
||||||
|
size: number
|
||||||
|
language: string
|
||||||
|
languages_url: string
|
||||||
|
html_url: string
|
||||||
|
url: string
|
||||||
|
link: string
|
||||||
|
ssh_url: string
|
||||||
|
clone_url: string
|
||||||
|
original_url: string
|
||||||
|
website: string
|
||||||
|
stars_count: number
|
||||||
|
forks_count: number
|
||||||
|
watchers_count: number
|
||||||
|
open_issues_count: number
|
||||||
|
open_pr_counter: number
|
||||||
|
release_counter: number
|
||||||
|
default_branch: string
|
||||||
|
archived: boolean
|
||||||
|
created_at: string
|
||||||
|
updated_at: string
|
||||||
|
archived_at: string
|
||||||
|
permissions: Permissions
|
||||||
|
has_issues: boolean
|
||||||
|
internal_tracker: InternalTracker
|
||||||
|
has_wiki: boolean
|
||||||
|
has_pull_requests: boolean
|
||||||
|
has_projects: boolean
|
||||||
|
has_releases: boolean
|
||||||
|
has_packages: boolean
|
||||||
|
has_actions: boolean
|
||||||
|
ignore_whitespace_conflicts: boolean
|
||||||
|
allow_merge_commits: boolean
|
||||||
|
allow_rebase: boolean
|
||||||
|
allow_rebase_explicit: boolean
|
||||||
|
allow_squash_merge: boolean
|
||||||
|
allow_rebase_update: boolean
|
||||||
|
default_delete_branch_after_merge: boolean
|
||||||
|
default_merge_style: string
|
||||||
|
default_allow_maintainer_edit: boolean
|
||||||
|
avatar_url: string
|
||||||
|
internal: boolean
|
||||||
|
mirror_interval: string
|
||||||
|
mirror_updated: string
|
||||||
|
repo_transfer: any
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Owner2 {
|
||||||
|
id: number
|
||||||
|
login: string
|
||||||
|
login_name: string
|
||||||
|
full_name: string
|
||||||
|
email: string
|
||||||
|
avatar_url: string
|
||||||
|
language: string
|
||||||
|
is_admin: boolean
|
||||||
|
last_login: string
|
||||||
|
created: string
|
||||||
|
restricted: boolean
|
||||||
|
active: boolean
|
||||||
|
prohibit_login: boolean
|
||||||
|
location: string
|
||||||
|
website: string
|
||||||
|
description: string
|
||||||
|
visibility: string
|
||||||
|
followers_count: number
|
||||||
|
following_count: number
|
||||||
|
starred_repos_count: number
|
||||||
|
username: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Permissions {
|
||||||
|
admin: boolean
|
||||||
|
push: boolean
|
||||||
|
pull: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface InternalTracker {
|
||||||
|
enable_time_tracker: boolean
|
||||||
|
allow_only_contributors_to_track_time: boolean
|
||||||
|
enable_issue_dependencies: boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Creator {
|
||||||
|
id: number
|
||||||
|
login: string
|
||||||
|
login_name: string
|
||||||
|
full_name: string
|
||||||
|
email: string
|
||||||
|
avatar_url: string
|
||||||
|
language: string
|
||||||
|
is_admin: boolean
|
||||||
|
last_login: string
|
||||||
|
created: string
|
||||||
|
restricted: boolean
|
||||||
|
active: boolean
|
||||||
|
prohibit_login: boolean
|
||||||
|
location: string
|
||||||
|
website: string
|
||||||
|
description: string
|
||||||
|
visibility: string
|
||||||
|
followers_count: number
|
||||||
|
following_count: number
|
||||||
|
starred_repos_count: number
|
||||||
|
username: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ForgejoFiles = ForgejoFile[]
|
||||||
|
|
||||||
|
export interface ForgejoFile {
|
||||||
|
id: number
|
||||||
|
Size: number
|
||||||
|
name: string
|
||||||
|
md5: string
|
||||||
|
sha1: string
|
||||||
|
sha256: string
|
||||||
|
sha512: string
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user