mirror of
https://github.com/ragestudio/relic.git
synced 2025-06-09 18:44:17 +00:00
Compare commits
30 Commits
Author | SHA1 | Date | |
---|---|---|---|
0e3889220d | |||
c996b215a3 | |||
87223efa21 | |||
6287f5fa50 | |||
98b6740839 | |||
e1d833a5f5 | |||
1e74f49e4e | |||
21152ac248 | |||
f863c27411 | |||
8b3610c518 | |||
bd719202c1 | |||
93201a5c19 | |||
9d61fc2e05 | |||
fda084d861 | |||
2789b30051 | |||
d9e9772d24 | |||
f1257ec7f3 | |||
67db27cf28 | |||
765999eb8a | |||
881d018bfc | |||
feaee17391 | |||
4ca2410f0a | |||
4cb93e9878 | |||
aa1f2f0913 | |||
64303dac7e | |||
1c6f871de0 | |||
3e7f9963e9 | |||
f1fba82cdf | |||
26753e6471 | |||
98d4676d8e |
0
.github/workflows/release.yml
vendored
Normal file → Executable file
0
.github/workflows/release.yml
vendored
Normal file → Executable file
0
.gitignore
vendored
Normal file → Executable file
0
.gitignore
vendored
Normal file → Executable file
4
package.json
Normal file → Executable file
4
package.json
Normal file → Executable file
@ -1,9 +1,5 @@
|
|||||||
{
|
{
|
||||||
"name": "@ragestudio/relic-core",
|
"name": "@ragestudio/relic-core",
|
||||||
"private": true,
|
|
||||||
"workspaces": [
|
|
||||||
"packages/*"
|
|
||||||
],
|
|
||||||
"repository": "https://github.com/srgooglo/rs_bundler",
|
"repository": "https://github.com/srgooglo/rs_bundler",
|
||||||
"author": "SrGooglo <srgooglo@ragestudio.net>",
|
"author": "SrGooglo <srgooglo@ragestudio.net>",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
|
0
packages/cli/bin
Normal file → Executable file
0
packages/cli/bin
Normal file → Executable file
0
packages/cli/package.json
Normal file → Executable file
0
packages/cli/package.json
Normal file → Executable file
0
packages/cli/src/index.js
Normal file → Executable file
0
packages/cli/src/index.js
Normal file → Executable file
0
packages/core/.swcrc
Normal file → Executable file
0
packages/core/.swcrc
Normal file → Executable file
84
packages/core/package.json
Normal file → Executable file
84
packages/core/package.json
Normal file → Executable file
@ -1,43 +1,45 @@
|
|||||||
{
|
{
|
||||||
"name": "@ragestudio/relic-core",
|
"name": "@ragestudio/relic-core",
|
||||||
"version": "0.17.1",
|
"version": "0.20.3",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"author": "RageStudio",
|
"author": "RageStudio",
|
||||||
"description": "RageStudio Relic, yet another package manager.",
|
"description": "RageStudio Relic, yet another package manager.",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
"files": [
|
"files": [
|
||||||
"dist",
|
"dist",
|
||||||
"src"
|
"src"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "hermes build",
|
"build": "hermes build",
|
||||||
"build:swc": "npx swc ./src --out-dir ./dist --strip-leading-paths"
|
"build:swc": "npx swc ./src --out-dir ./dist --strip-leading-paths"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@foxify/events": "^2.1.0",
|
"@foxify/events": "^2.1.0",
|
||||||
"adm-zip": "^0.5.12",
|
"adm-zip": "^0.5.12",
|
||||||
"axios": "^1.6.8",
|
"aria2": "^4.1.2",
|
||||||
"checksum": "^1.0.0",
|
"axios": "^1.6.8",
|
||||||
"cli-color": "^2.0.4",
|
"checksum": "^1.0.0",
|
||||||
"cli-progress": "^3.12.0",
|
"cli-color": "^2.0.4",
|
||||||
"deep-object-diff": "^1.1.9",
|
"cli-progress": "^3.12.0",
|
||||||
"extends-classes": "^1.0.5",
|
"deep-object-diff": "^1.1.9",
|
||||||
"googleapis": "^134.0.0",
|
"extends-classes": "^1.0.5",
|
||||||
"human-format": "^1.2.0",
|
"googleapis": "^134.0.0",
|
||||||
"merge-stream": "^2.0.0",
|
"human-format": "^1.2.0",
|
||||||
"module-alias": "^2.2.3",
|
"merge-stream": "^2.0.0",
|
||||||
"node-7z": "^3.0.0",
|
"module-alias": "^2.2.3",
|
||||||
"open": "8.4.2",
|
"node-7z": "^3.0.0",
|
||||||
"request": "^2.88.2",
|
"open": "8.4.2",
|
||||||
"rimraf": "^5.0.5",
|
"request": "^2.88.2",
|
||||||
"signal-exit": "^4.1.0",
|
"rimraf": "^5.0.5",
|
||||||
"unzipper": "^0.10.14",
|
"signal-exit": "^4.1.0",
|
||||||
"upath": "^2.0.1",
|
"unzipper": "^0.10.14",
|
||||||
"uuid": "^9.0.1",
|
"upath": "^2.0.1",
|
||||||
"winston": "^3.13.0"
|
"uuid": "^9.0.1",
|
||||||
},
|
"webtorrent": "^2.4.1",
|
||||||
"devDependencies": {
|
"winston": "^3.13.0"
|
||||||
"@swc/cli": "^0.3.12",
|
},
|
||||||
"@swc/core": "^1.4.11"
|
"devDependencies": {
|
||||||
}
|
"@swc/cli": "^0.3.12",
|
||||||
|
"@swc/core": "^1.4.11"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
8
packages/core/src/classes/ManifestAuthDB.js
Normal file → Executable file
8
packages/core/src/classes/ManifestAuthDB.js
Normal file → Executable file
@ -33,4 +33,12 @@ export default class ManifestAuthService {
|
|||||||
|
|
||||||
return await db.data[pkg_id]
|
return await db.data[pkg_id]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static delete = async (pkg_id) => {
|
||||||
|
const db = await this.withDB()
|
||||||
|
|
||||||
|
return await db.update((data) => {
|
||||||
|
delete data[pkg_id]
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
0
packages/core/src/classes/ManifestConfig.js
Normal file → Executable file
0
packages/core/src/classes/ManifestConfig.js
Normal file → Executable file
0
packages/core/src/classes/PatchManager.js
Normal file → Executable file
0
packages/core/src/classes/PatchManager.js
Normal file → Executable file
57
packages/core/src/classes/Settings.js
Executable file
57
packages/core/src/classes/Settings.js
Executable file
@ -0,0 +1,57 @@
|
|||||||
|
import fs from "node:fs"
|
||||||
|
import path from "node:path"
|
||||||
|
import Vars from "../vars"
|
||||||
|
|
||||||
|
const settingsPath = path.resolve(Vars.runtime_path, "settings.json")
|
||||||
|
|
||||||
|
export default class Settings {
|
||||||
|
static filePath = settingsPath
|
||||||
|
|
||||||
|
static async initialize() {
|
||||||
|
if (!fs.existsSync(settingsPath)) {
|
||||||
|
await fs.promises.writeFile(settingsPath, "{}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static async read() {
|
||||||
|
return JSON.parse(await fs.promises.readFile(settingsPath, "utf8"))
|
||||||
|
}
|
||||||
|
|
||||||
|
static async write(data) {
|
||||||
|
await fs.promises.writeFile(settingsPath, JSON.stringify(data, null, 2))
|
||||||
|
}
|
||||||
|
|
||||||
|
static async get(key) {
|
||||||
|
const data = await this.read()
|
||||||
|
|
||||||
|
if (key) {
|
||||||
|
return data[key]
|
||||||
|
}
|
||||||
|
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
|
||||||
|
static async has(key) {
|
||||||
|
const data = await this.read()
|
||||||
|
|
||||||
|
return key in data
|
||||||
|
}
|
||||||
|
|
||||||
|
static async set(key, value) {
|
||||||
|
const data = await this.read()
|
||||||
|
|
||||||
|
data[key] = value
|
||||||
|
|
||||||
|
await this.write(data)
|
||||||
|
}
|
||||||
|
|
||||||
|
static async delete(key) {
|
||||||
|
const data = await this.read()
|
||||||
|
|
||||||
|
delete data[key]
|
||||||
|
|
||||||
|
await this.write(data)
|
||||||
|
|
||||||
|
return data
|
||||||
|
}
|
||||||
|
}
|
7
packages/core/src/db.js
Normal file → Executable file
7
packages/core/src/db.js
Normal file → Executable file
@ -2,7 +2,6 @@ import { JSONFilePreset } from "./libraries/lowdb/presets/node"
|
|||||||
import Vars from "./vars"
|
import Vars from "./vars"
|
||||||
import pkg from "../package.json"
|
import pkg from "../package.json"
|
||||||
import fs from "node:fs"
|
import fs from "node:fs"
|
||||||
import lodash from "lodash"
|
|
||||||
|
|
||||||
export default class DB {
|
export default class DB {
|
||||||
static get defaultRoot() {
|
static get defaultRoot() {
|
||||||
@ -94,11 +93,15 @@ export default class DB {
|
|||||||
static async updatePackageById(pkg_id, obj) {
|
static async updatePackageById(pkg_id, obj) {
|
||||||
let pkg = await this.getPackages(pkg_id)
|
let pkg = await this.getPackages(pkg_id)
|
||||||
|
|
||||||
|
|
||||||
if (!pkg) {
|
if (!pkg) {
|
||||||
throw new Error("Package not found")
|
throw new Error("Package not found")
|
||||||
}
|
}
|
||||||
|
|
||||||
return await this.writePackage(lodash.merge({ ...pkg }, obj))
|
return await this.writePackage({
|
||||||
|
...pkg,
|
||||||
|
...obj,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
static async deletePackage(pkg_id) {
|
static async deletePackage(pkg_id) {
|
||||||
|
2
packages/core/src/generic_steps/git_clone.js
Normal file → Executable file
2
packages/core/src/generic_steps/git_clone.js
Normal file → Executable file
@ -14,7 +14,7 @@ export default async (pkg, step) => {
|
|||||||
|
|
||||||
const Log = Logger.child({ service: `GIT|${pkg.id}` })
|
const Log = Logger.child({ service: `GIT|${pkg.id}` })
|
||||||
|
|
||||||
const gitCMD = fs.existsSync(Vars.git_path) ? `${Vars.git_path}` : "git"
|
const gitCMD = fs.existsSync(Vars.git_bin) ? `${Vars.git_bin}` : "git"
|
||||||
const final_path = upath.normalizeSafe(path.resolve(pkg.install_path, step.path))
|
const final_path = upath.normalizeSafe(path.resolve(pkg.install_path, step.path))
|
||||||
|
|
||||||
if (!fs.existsSync(final_path)) {
|
if (!fs.existsSync(final_path)) {
|
||||||
|
2
packages/core/src/generic_steps/git_pull.js
Normal file → Executable file
2
packages/core/src/generic_steps/git_pull.js
Normal file → Executable file
@ -13,7 +13,7 @@ export default async (pkg, step) => {
|
|||||||
|
|
||||||
const Log = Logger.child({ service: `GIT|${pkg.id}` })
|
const Log = Logger.child({ service: `GIT|${pkg.id}` })
|
||||||
|
|
||||||
const gitCMD = fs.existsSync(Vars.git_path) ? `${Vars.git_path}` : "git"
|
const gitCMD = fs.existsSync(Vars.git_bin) ? `${Vars.git_bin}` : "git"
|
||||||
const _path = path.resolve(pkg.install_path, step.path)
|
const _path = path.resolve(pkg.install_path, step.path)
|
||||||
|
|
||||||
global._relic_eventBus.emit(`pkg:update:state`, {
|
global._relic_eventBus.emit(`pkg:update:state`, {
|
||||||
|
2
packages/core/src/generic_steps/git_reset.js
Normal file → Executable file
2
packages/core/src/generic_steps/git_reset.js
Normal file → Executable file
@ -14,7 +14,7 @@ export default async (pkg, step) => {
|
|||||||
|
|
||||||
const Log = Logger.child({ service: `GIT|${pkg.id}` })
|
const Log = Logger.child({ service: `GIT|${pkg.id}` })
|
||||||
|
|
||||||
const gitCMD = fs.existsSync(Vars.git_path) ? `${Vars.git_path}` : "git"
|
const gitCMD = fs.existsSync(Vars.git_bin) ? `${Vars.git_bin}` : "git"
|
||||||
|
|
||||||
const _path = path.resolve(pkg.install_path, step.path)
|
const _path = path.resolve(pkg.install_path, step.path)
|
||||||
const from = step.from ?? "HEAD"
|
const from = step.from ?? "HEAD"
|
||||||
|
21
packages/core/src/generic_steps/http.js
Normal file → Executable file
21
packages/core/src/generic_steps/http.js
Normal file → Executable file
@ -6,7 +6,7 @@ import downloadHttpFile from "../helpers/downloadHttpFile"
|
|||||||
import parseStringVars from "../utils/parseStringVars"
|
import parseStringVars from "../utils/parseStringVars"
|
||||||
import extractFile from "../utils/extractFile"
|
import extractFile from "../utils/extractFile"
|
||||||
|
|
||||||
export default async (pkg, step, logger) => {
|
export default async (pkg, step, logger, abortController) => {
|
||||||
if (!step.path) {
|
if (!step.path) {
|
||||||
step.path = `./${path.basename(step.url)}`
|
step.path = `./${path.basename(step.url)}`
|
||||||
}
|
}
|
||||||
@ -28,13 +28,18 @@ export default async (pkg, step, logger) => {
|
|||||||
|
|
||||||
fs.mkdirSync(path.resolve(_path, ".."), { recursive: true })
|
fs.mkdirSync(path.resolve(_path, ".."), { recursive: true })
|
||||||
|
|
||||||
await downloadHttpFile(step.url, _path, (progress) => {
|
await downloadHttpFile(
|
||||||
global._relic_eventBus.emit(`pkg:update:state`, {
|
step.url,
|
||||||
id: pkg.id,
|
_path,
|
||||||
use_id_only: true,
|
(progress) => {
|
||||||
status_text: `Downloaded ${progress.transferredString} / ${progress.totalString} | ${progress.speedString}/s`,
|
global._relic_eventBus.emit(`pkg:update:state`, {
|
||||||
})
|
id: pkg.id,
|
||||||
})
|
use_id_only: true,
|
||||||
|
status_text: `Downloaded ${progress.transferredString} / ${progress.totalString} | ${progress.speedString}/s`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
abortController
|
||||||
|
)
|
||||||
|
|
||||||
logger.info(`Downloaded finished.`)
|
logger.info(`Downloaded finished.`)
|
||||||
|
|
||||||
|
11
packages/core/src/generic_steps/index.js
Normal file → Executable file
11
packages/core/src/generic_steps/index.js
Normal file → Executable file
@ -4,22 +4,25 @@ import ISM_GIT_CLONE from "./git_clone"
|
|||||||
import ISM_GIT_PULL from "./git_pull"
|
import ISM_GIT_PULL from "./git_pull"
|
||||||
import ISM_GIT_RESET from "./git_reset"
|
import ISM_GIT_RESET from "./git_reset"
|
||||||
import ISM_HTTP from "./http"
|
import ISM_HTTP from "./http"
|
||||||
|
import ISM_TORRENT from "./torrent"
|
||||||
|
|
||||||
const InstallationStepsMethods = {
|
const InstallationStepsMethods = {
|
||||||
git_clone: ISM_GIT_CLONE,
|
git_clone: ISM_GIT_CLONE,
|
||||||
git_pull: ISM_GIT_PULL,
|
git_pull: ISM_GIT_PULL,
|
||||||
git_reset: ISM_GIT_RESET,
|
git_reset: ISM_GIT_RESET,
|
||||||
http_file: ISM_HTTP,
|
http_file: ISM_HTTP,
|
||||||
|
torrent: ISM_TORRENT,
|
||||||
}
|
}
|
||||||
|
|
||||||
const StepsOrders = [
|
const StepsOrders = [
|
||||||
"git_clones",
|
"git_clones",
|
||||||
"git_pull",
|
"git_pull",
|
||||||
"git_reset",
|
"git_reset",
|
||||||
|
"torrent",
|
||||||
"http_file",
|
"http_file",
|
||||||
]
|
]
|
||||||
|
|
||||||
export default async function processGenericSteps(pkg, steps, logger = Logger) {
|
export default async function processGenericSteps(pkg, steps, logger = Logger, abortController) {
|
||||||
logger.info(`Processing generic steps...`)
|
logger.info(`Processing generic steps...`)
|
||||||
|
|
||||||
if (!Array.isArray(steps)) {
|
if (!Array.isArray(steps)) {
|
||||||
@ -37,11 +40,15 @@ export default async function processGenericSteps(pkg, steps, logger = Logger) {
|
|||||||
for await (let step of steps) {
|
for await (let step of steps) {
|
||||||
step.type = step.type.toLowerCase()
|
step.type = step.type.toLowerCase()
|
||||||
|
|
||||||
|
if (abortController?.signal?.aborted) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
if (!InstallationStepsMethods[step.type]) {
|
if (!InstallationStepsMethods[step.type]) {
|
||||||
throw new Error(`Unknown step: ${step.type}`)
|
throw new Error(`Unknown step: ${step.type}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
await InstallationStepsMethods[step.type](pkg, step, logger)
|
await InstallationStepsMethods[step.type](pkg, step, logger, abortController)
|
||||||
}
|
}
|
||||||
|
|
||||||
return pkg
|
return pkg
|
||||||
|
48
packages/core/src/generic_steps/torrent.js
Executable file
48
packages/core/src/generic_steps/torrent.js
Executable file
@ -0,0 +1,48 @@
|
|||||||
|
import path from "node:path"
|
||||||
|
import fs from "node:fs"
|
||||||
|
|
||||||
|
import parseStringVars from "../utils/parseStringVars"
|
||||||
|
import downloadTorrent from "../helpers/downloadTorrent"
|
||||||
|
|
||||||
|
export default async (pkg, step, logger, abortController) => {
|
||||||
|
if (!step.magnet) {
|
||||||
|
throw new Error(`Magnet is required for torrent step`)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof step.path === "undefined") {
|
||||||
|
step.path = `.`
|
||||||
|
}
|
||||||
|
|
||||||
|
step.path = await parseStringVars(step.path, pkg)
|
||||||
|
|
||||||
|
let _path = path.resolve(pkg.install_path, step.path)
|
||||||
|
|
||||||
|
global._relic_eventBus.emit(`pkg:update:state`, {
|
||||||
|
id: pkg.id,
|
||||||
|
status_text: `Preparing torrent...`,
|
||||||
|
})
|
||||||
|
|
||||||
|
logger.info(`Preparing torrent with magnet => [${step.magnet}]`)
|
||||||
|
|
||||||
|
if (step.tmp) {
|
||||||
|
_path = path.resolve(os.tmpdir(), String(new Date().getTime()))
|
||||||
|
}
|
||||||
|
|
||||||
|
const parentDir = path.resolve(_path, "..")
|
||||||
|
|
||||||
|
if (!fs.existsSync(parentDir)) {
|
||||||
|
fs.mkdirSync(parentDir, { recursive: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
await downloadTorrent(step.magnet, _path, {
|
||||||
|
onProgress: (progress) => {
|
||||||
|
global._relic_eventBus.emit(`pkg:update:state`, {
|
||||||
|
id: pkg.id,
|
||||||
|
use_id_only: true,
|
||||||
|
status_text: `Downloaded ${progress.transferredString} / ${progress.totalString} | ${progress.speedString}/s`,
|
||||||
|
})
|
||||||
|
},
|
||||||
|
taskId: pkg.id
|
||||||
|
})
|
||||||
|
|
||||||
|
}
|
2
packages/core/src/handlers/apply.js
Normal file → Executable file
2
packages/core/src/handlers/apply.js
Normal file → Executable file
@ -59,6 +59,8 @@ export default async function apply(pkg_id, changes = {}) {
|
|||||||
|
|
||||||
await patches.remove(findPatch(manifest.patches, pkg.applied_patches, changes, false))
|
await patches.remove(findPatch(manifest.patches, pkg.applied_patches, changes, false))
|
||||||
await patches.patch(findPatch(manifest.patches, pkg.applied_patches, changes, true))
|
await patches.patch(findPatch(manifest.patches, pkg.applied_patches, changes, true))
|
||||||
|
|
||||||
|
pkg = await DB.getPackages(pkg_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changes.config) {
|
if (changes.config) {
|
||||||
|
0
packages/core/src/handlers/authorize.js
Normal file → Executable file
0
packages/core/src/handlers/authorize.js
Normal file → Executable file
44
packages/core/src/handlers/cancelInstall.js
Executable file
44
packages/core/src/handlers/cancelInstall.js
Executable file
@ -0,0 +1,44 @@
|
|||||||
|
import Logger from "../logger"
|
||||||
|
|
||||||
|
import DB from "../db"
|
||||||
|
|
||||||
|
import UninstallHandler from "./uninstall"
|
||||||
|
|
||||||
|
const BaseLog = Logger.child({ service: "CANCEL_INSTALL" })
|
||||||
|
|
||||||
|
export default async function reinstall(pkg_id) {
|
||||||
|
try {
|
||||||
|
const pkg = await DB.getPackages(pkg_id)
|
||||||
|
|
||||||
|
if (!pkg) {
|
||||||
|
BaseLog.info(`Package not found [${pkg_id}]`)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
global._relic_eventBus.emit(`pkg:install:cancel`, pkg_id)
|
||||||
|
global._relic_eventBus.emit(`pkg:install:cancel:${pkg_id}`, pkg_id)
|
||||||
|
global._relic_eventBus.emit(`task:cancel:${pkg_id}`, pkg_id)
|
||||||
|
|
||||||
|
const task = globalThis.relic_core.tasks.find((task) => task.id === pkg_id)
|
||||||
|
|
||||||
|
if (task) {
|
||||||
|
BaseLog.warn(`Task not found [${pkg_id}]`)
|
||||||
|
await task.abortController.abort()
|
||||||
|
}
|
||||||
|
|
||||||
|
await UninstallHandler(pkg_id)
|
||||||
|
|
||||||
|
return pkg
|
||||||
|
} catch (error) {
|
||||||
|
global._relic_eventBus.emit(`pkg:error`, {
|
||||||
|
event: "cancel_install",
|
||||||
|
id: pkg_id,
|
||||||
|
error
|
||||||
|
})
|
||||||
|
|
||||||
|
BaseLog.error(`Failed to cancel installation package [${pkg_id}]`, error)
|
||||||
|
BaseLog.error(error.stack)
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
0
packages/core/src/handlers/checkUpdate.js
Normal file → Executable file
0
packages/core/src/handlers/checkUpdate.js
Normal file → Executable file
28
packages/core/src/handlers/deauthorize.js
Executable file
28
packages/core/src/handlers/deauthorize.js
Executable file
@ -0,0 +1,28 @@
|
|||||||
|
import ManifestAuthDB from "../classes/ManifestAuthDB"
|
||||||
|
import DB from "../db"
|
||||||
|
|
||||||
|
import Logger from "../logger"
|
||||||
|
|
||||||
|
const Log = Logger.child({ service: "AUTH" })
|
||||||
|
|
||||||
|
export default async (pkg_id) => {
|
||||||
|
if (!pkg_id) {
|
||||||
|
Log.error("pkg_id is required")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
const pkg = await DB.getPackages(pkg_id)
|
||||||
|
|
||||||
|
if (!pkg) {
|
||||||
|
Log.error("Package not found")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
Log.info(`Deleting auth for [${pkg_id}]`)
|
||||||
|
|
||||||
|
await ManifestAuthDB.delete(pkg_id)
|
||||||
|
|
||||||
|
global._relic_eventBus.emit("pkg:deauthorized", pkg)
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
2
packages/core/src/handlers/execute.js
Normal file → Executable file
2
packages/core/src/handlers/execute.js
Normal file → Executable file
@ -43,6 +43,8 @@ export default async function execute(pkg_id, { useRemote = false, force = false
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BaseLog.info(`Executing manifest > [${manifestPath}]`)
|
||||||
|
|
||||||
global._relic_eventBus.emit(`pkg:update:state`, {
|
global._relic_eventBus.emit(`pkg:update:state`, {
|
||||||
id: pkg.id,
|
id: pkg.id,
|
||||||
last_status: "loading",
|
last_status: "loading",
|
||||||
|
61
packages/core/src/handlers/install.js
Normal file → Executable file
61
packages/core/src/handlers/install.js
Normal file → Executable file
@ -10,8 +10,9 @@ import Apply from "../handlers/apply"
|
|||||||
|
|
||||||
const BaseLog = Logger.child({ service: "INSTALLER" })
|
const BaseLog = Logger.child({ service: "INSTALLER" })
|
||||||
|
|
||||||
export default async function install(manifest) {
|
export default async function install(manifest, options = {}) {
|
||||||
let id = null
|
let id = null
|
||||||
|
let abortController = new AbortController()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
BaseLog.info(`Invoking new installation...`)
|
BaseLog.info(`Invoking new installation...`)
|
||||||
@ -23,10 +24,20 @@ export default async function install(manifest) {
|
|||||||
|
|
||||||
id = manifest.constructor.id
|
id = manifest.constructor.id
|
||||||
|
|
||||||
|
globalThis.relic_core.tasks.push({
|
||||||
|
type: "install",
|
||||||
|
id: id,
|
||||||
|
abortController: abortController,
|
||||||
|
})
|
||||||
|
|
||||||
const Log = BaseLog.child({ service: `INSTALLER|${id}` })
|
const Log = BaseLog.child({ service: `INSTALLER|${id}` })
|
||||||
|
|
||||||
Log.info(`Creating install path [${manifest.install_path}]`)
|
Log.info(`Creating install path [${manifest.install_path}]`)
|
||||||
|
|
||||||
|
if (abortController.signal.aborted) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
if (fs.existsSync(manifest.install_path)) {
|
if (fs.existsSync(manifest.install_path)) {
|
||||||
Log.info(`Package already exists, removing...`)
|
Log.info(`Package already exists, removing...`)
|
||||||
await fs.rmSync(manifest.install_path, { recursive: true })
|
await fs.rmSync(manifest.install_path, { recursive: true })
|
||||||
@ -36,13 +47,21 @@ export default async function install(manifest) {
|
|||||||
|
|
||||||
Log.info(`Initializing manifest...`)
|
Log.info(`Initializing manifest...`)
|
||||||
|
|
||||||
|
if (abortController.signal.aborted) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof manifest.initialize === "function") {
|
if (typeof manifest.initialize === "function") {
|
||||||
await manifest.initialize()
|
await manifest.initialize()
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.info(`Appending to db...`)
|
Log.info(`Appending to db...`)
|
||||||
|
|
||||||
const pkg = DB.defaultPackageState({
|
if (abortController.signal.aborted) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
let pkg = DB.defaultPackageState({
|
||||||
...manifest.constructor,
|
...manifest.constructor,
|
||||||
id: id,
|
id: id,
|
||||||
name: manifest.constructor.pkg_name,
|
name: manifest.constructor.pkg_name,
|
||||||
@ -60,6 +79,10 @@ export default async function install(manifest) {
|
|||||||
|
|
||||||
global._relic_eventBus.emit("pkg:new", pkg)
|
global._relic_eventBus.emit("pkg:new", pkg)
|
||||||
|
|
||||||
|
if (abortController.signal.aborted) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
if (manifest.configuration) {
|
if (manifest.configuration) {
|
||||||
Log.info(`Applying default config to package...`)
|
Log.info(`Applying default config to package...`)
|
||||||
|
|
||||||
@ -70,6 +93,10 @@ export default async function install(manifest) {
|
|||||||
}, {})
|
}, {})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (abortController.signal.aborted) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof manifest.beforeInstall === "function") {
|
if (typeof manifest.beforeInstall === "function") {
|
||||||
Log.info(`Executing beforeInstall hook...`)
|
Log.info(`Executing beforeInstall hook...`)
|
||||||
|
|
||||||
@ -81,7 +108,11 @@ export default async function install(manifest) {
|
|||||||
await manifest.beforeInstall(pkg)
|
await manifest.beforeInstall(pkg)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Array.isArray(manifest.installSteps)) {
|
if (abortController.signal.aborted) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Array.isArray(manifest.installSteps) && !options.noInstallSteps) {
|
||||||
Log.info(`Executing generic install steps...`)
|
Log.info(`Executing generic install steps...`)
|
||||||
|
|
||||||
global._relic_eventBus.emit(`pkg:update:state`, {
|
global._relic_eventBus.emit(`pkg:update:state`, {
|
||||||
@ -89,7 +120,11 @@ export default async function install(manifest) {
|
|||||||
status_text: `Performing generic install steps...`,
|
status_text: `Performing generic install steps...`,
|
||||||
})
|
})
|
||||||
|
|
||||||
await GenericSteps(pkg, manifest.installSteps, Log)
|
await GenericSteps(pkg, manifest.installSteps, Log, abortController)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (abortController.signal.aborted) {
|
||||||
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof manifest.afterInstall === "function") {
|
if (typeof manifest.afterInstall === "function") {
|
||||||
@ -112,6 +147,10 @@ export default async function install(manifest) {
|
|||||||
|
|
||||||
const finalPath = `${manifest.install_path}/.rmanifest`
|
const finalPath = `${manifest.install_path}/.rmanifest`
|
||||||
|
|
||||||
|
if (abortController.signal.aborted) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
if (fs.existsSync(finalPath)) {
|
if (fs.existsSync(finalPath)) {
|
||||||
await fs.promises.unlink(finalPath)
|
await fs.promises.unlink(finalPath)
|
||||||
}
|
}
|
||||||
@ -129,6 +168,10 @@ export default async function install(manifest) {
|
|||||||
|
|
||||||
await DB.writePackage(pkg)
|
await DB.writePackage(pkg)
|
||||||
|
|
||||||
|
if (abortController.signal.aborted) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
if (manifest.patches) {
|
if (manifest.patches) {
|
||||||
const defaultPatches = manifest.patches.filter((patch) => patch.default)
|
const defaultPatches = manifest.patches.filter((patch) => patch.default)
|
||||||
|
|
||||||
@ -140,7 +183,7 @@ export default async function install(manifest) {
|
|||||||
status_text: `Applying default patches...`,
|
status_text: `Applying default patches...`,
|
||||||
})
|
})
|
||||||
|
|
||||||
await Apply(id, {
|
pkg = await Apply(id, {
|
||||||
patches: Object.fromEntries(defaultPatches.map((patch) => [patch.id, true])),
|
patches: Object.fromEntries(defaultPatches.map((patch) => [patch.id, true])),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -148,8 +191,14 @@ export default async function install(manifest) {
|
|||||||
|
|
||||||
pkg.last_status = "installed"
|
pkg.last_status = "installed"
|
||||||
|
|
||||||
|
if (abortController.signal.aborted) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
await DB.writePackage(pkg)
|
await DB.writePackage(pkg)
|
||||||
|
|
||||||
|
globalThis.relic_core.tasks.filter((task) => task.id !== id)
|
||||||
|
|
||||||
global._relic_eventBus.emit(`pkg:update:state`, {
|
global._relic_eventBus.emit(`pkg:update:state`, {
|
||||||
...pkg,
|
...pkg,
|
||||||
id: pkg.id,
|
id: pkg.id,
|
||||||
@ -175,6 +224,8 @@ export default async function install(manifest) {
|
|||||||
status_text: `Installation failed`,
|
status_text: `Installation failed`,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
globalThis.relic_core.tasks.filter((task) => task.id !== id)
|
||||||
|
|
||||||
BaseLog.error(`Error during installation of package [${id}] >`, error)
|
BaseLog.error(`Error during installation of package [${id}] >`, error)
|
||||||
BaseLog.error(error.stack)
|
BaseLog.error(error.stack)
|
||||||
|
|
||||||
|
0
packages/core/src/handlers/lastOperationRetry.js
Normal file → Executable file
0
packages/core/src/handlers/lastOperationRetry.js
Normal file → Executable file
0
packages/core/src/handlers/list.js
Normal file → Executable file
0
packages/core/src/handlers/list.js
Normal file → Executable file
0
packages/core/src/handlers/read.js
Normal file → Executable file
0
packages/core/src/handlers/read.js
Normal file → Executable file
35
packages/core/src/handlers/reinstall.js
Executable file
35
packages/core/src/handlers/reinstall.js
Executable file
@ -0,0 +1,35 @@
|
|||||||
|
import Logger from "../logger"
|
||||||
|
|
||||||
|
import DB from "../db"
|
||||||
|
|
||||||
|
import UninstallHandler from "./uninstall"
|
||||||
|
import InstallHandler from "./install"
|
||||||
|
|
||||||
|
const BaseLog = Logger.child({ service: "REINSTALL" })
|
||||||
|
|
||||||
|
export default async function reinstall(pkg_id) {
|
||||||
|
try {
|
||||||
|
const pkg = await DB.getPackages(pkg_id)
|
||||||
|
|
||||||
|
if (!pkg) {
|
||||||
|
BaseLog.info(`Package not found [${pkg_id}]`)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
await UninstallHandler(pkg_id)
|
||||||
|
await InstallHandler(pkg.remote_manifest)
|
||||||
|
|
||||||
|
return pkg
|
||||||
|
} catch (error) {
|
||||||
|
global._relic_eventBus.emit(`pkg:error`, {
|
||||||
|
event: "reinstall",
|
||||||
|
id: pkg_id,
|
||||||
|
error
|
||||||
|
})
|
||||||
|
|
||||||
|
BaseLog.error(`Failed to reinstall package [${pkg_id}]`, error)
|
||||||
|
BaseLog.error(error.stack)
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
}
|
0
packages/core/src/handlers/uninstall.js
Normal file → Executable file
0
packages/core/src/handlers/uninstall.js
Normal file → Executable file
0
packages/core/src/handlers/update.js
Normal file → Executable file
0
packages/core/src/handlers/update.js
Normal file → Executable file
3
packages/core/src/helpers/downloadHttpFile.js
Normal file → Executable file
3
packages/core/src/helpers/downloadHttpFile.js
Normal file → Executable file
@ -9,7 +9,7 @@ function convertSize(size) {
|
|||||||
})}B`
|
})}B`
|
||||||
}
|
}
|
||||||
|
|
||||||
export default async (url, destination, progressCallback) => {
|
export default async (url, destination, progressCallback, abortController) => {
|
||||||
const progressBar = new cliProgress.SingleBar({
|
const progressBar = new cliProgress.SingleBar({
|
||||||
format: "[{bar}] {percentage}% | {total_formatted} | {speed}/s | {eta_formatted}",
|
format: "[{bar}] {percentage}% | {total_formatted} | {speed}/s | {eta_formatted}",
|
||||||
barCompleteChar: "\u2588",
|
barCompleteChar: "\u2588",
|
||||||
@ -19,6 +19,7 @@ export default async (url, destination, progressCallback) => {
|
|||||||
|
|
||||||
const { data: remoteStream, headers } = await axios.get(url, {
|
const { data: remoteStream, headers } = await axios.get(url, {
|
||||||
responseType: "stream",
|
responseType: "stream",
|
||||||
|
signal: abortController?.signal,
|
||||||
})
|
})
|
||||||
|
|
||||||
const localStream = fs.createWriteStream(destination)
|
const localStream = fs.createWriteStream(destination)
|
||||||
|
140
packages/core/src/helpers/downloadTorrent.js
Executable file
140
packages/core/src/helpers/downloadTorrent.js
Executable file
@ -0,0 +1,140 @@
|
|||||||
|
import humanFormat from "human-format"
|
||||||
|
import aria2 from "aria2"
|
||||||
|
|
||||||
|
function convertSize(size) {
|
||||||
|
return `${humanFormat(size, {
|
||||||
|
decimals: 2,
|
||||||
|
})}B`
|
||||||
|
}
|
||||||
|
|
||||||
|
export default async function downloadTorrent(
|
||||||
|
magnet,
|
||||||
|
destination,
|
||||||
|
{
|
||||||
|
onStart,
|
||||||
|
onProgress,
|
||||||
|
onDone,
|
||||||
|
onError,
|
||||||
|
taskId,
|
||||||
|
} = {}
|
||||||
|
) {
|
||||||
|
let progressInterval = null
|
||||||
|
let tickProgress = {
|
||||||
|
total: 0,
|
||||||
|
transferred: 0,
|
||||||
|
speed: 0,
|
||||||
|
|
||||||
|
totalString: "0B",
|
||||||
|
transferredString: "0B",
|
||||||
|
speedString: "0B/s",
|
||||||
|
}
|
||||||
|
|
||||||
|
const client = new aria2({
|
||||||
|
host: "localhost",
|
||||||
|
port: 6800,
|
||||||
|
secure: false,
|
||||||
|
secret: "",
|
||||||
|
path: "/jsonrpc"
|
||||||
|
})
|
||||||
|
|
||||||
|
await client.open()
|
||||||
|
|
||||||
|
let downloadId = await client.call(
|
||||||
|
"addUri",
|
||||||
|
[magnet],
|
||||||
|
{
|
||||||
|
dir: destination,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
async function stopDownload() {
|
||||||
|
await client.call("remove", downloadId)
|
||||||
|
clearInterval(progressInterval)
|
||||||
|
}
|
||||||
|
|
||||||
|
await new Promise(async (resolve, reject) => {
|
||||||
|
if (typeof onStart === "function") {
|
||||||
|
onStart()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (taskId) {
|
||||||
|
global._relic_eventBus.once(`task:cancel:${taskId}`, stopDownload)
|
||||||
|
}
|
||||||
|
|
||||||
|
progressInterval = setInterval(async () => {
|
||||||
|
const data = await client.call("tellStatus", downloadId)
|
||||||
|
|
||||||
|
console.log(data)
|
||||||
|
|
||||||
|
if (data.status === "complete") {
|
||||||
|
if (Array.isArray(data.followedBy) && data.followedBy[0]) {
|
||||||
|
// replace downloadId
|
||||||
|
downloadId = data.followedBy[0]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tickProgress.total = parseInt(data.totalLength)
|
||||||
|
tickProgress.speed = parseInt(data.downloadSpeed)
|
||||||
|
tickProgress.transferred = parseInt(data.completedLength)
|
||||||
|
tickProgress.connections = data.connections
|
||||||
|
|
||||||
|
tickProgress.transferredString = convertSize(tickProgress.transferred)
|
||||||
|
tickProgress.totalString = convertSize(tickProgress.total)
|
||||||
|
tickProgress.speedString = convertSize(tickProgress.speed)
|
||||||
|
|
||||||
|
if (typeof onProgress === "function") {
|
||||||
|
onProgress(tickProgress)
|
||||||
|
}
|
||||||
|
}, 1000)
|
||||||
|
|
||||||
|
client.on("onDownloadStart", async ([{ gid }]) => {
|
||||||
|
const data = await client.call("tellStatus", gid)
|
||||||
|
|
||||||
|
console.log(data)
|
||||||
|
|
||||||
|
if (typeof data.following !== "undefined") {
|
||||||
|
if (data.following === downloadId) {
|
||||||
|
downloadId = data.gid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
client.on("onBtDownloadComplete", ([{ gid }]) => {
|
||||||
|
if (gid !== downloadId) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof onDone === "function") {
|
||||||
|
onDone()
|
||||||
|
}
|
||||||
|
|
||||||
|
stopDownload()
|
||||||
|
|
||||||
|
return resolve({
|
||||||
|
downloadId,
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
client.on("onDownloadError", ([{ gid }]) => {
|
||||||
|
if (gid !== downloadId) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
stopDownload()
|
||||||
|
|
||||||
|
if (typeof onError === "function") {
|
||||||
|
onError()
|
||||||
|
}
|
||||||
|
|
||||||
|
return reject()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
await client.call("remove", downloadId)
|
||||||
|
|
||||||
|
if (taskId) {
|
||||||
|
global._relic_eventBus.off(`task:cancel:${taskId}`, stopDownload)
|
||||||
|
}
|
||||||
|
|
||||||
|
return downloadId
|
||||||
|
}
|
0
packages/core/src/helpers/sendToRender.js
Normal file → Executable file
0
packages/core/src/helpers/sendToRender.js
Normal file → Executable file
2
packages/core/src/helpers/setup.js
Normal file → Executable file
2
packages/core/src/helpers/setup.js
Normal file → Executable file
@ -69,7 +69,7 @@ export default async () => {
|
|||||||
await fs.promises.mkdir(path.resolve(Vars.binaries_path, prerequisite.id), { recursive: true })
|
await fs.promises.mkdir(path.resolve(Vars.binaries_path, prerequisite.id), { recursive: true })
|
||||||
|
|
||||||
if (typeof prerequisite.url === "function") {
|
if (typeof prerequisite.url === "function") {
|
||||||
prerequisite.url = await prerequisite.url(resolveOs(), os.arch())
|
prerequisite.url = await prerequisite.url(os.platform(), os.arch())
|
||||||
Log.info(`Resolved url: ${prerequisite.url}`)
|
Log.info(`Resolved url: ${prerequisite.url}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
118
packages/core/src/index.js
Normal file → Executable file
118
packages/core/src/index.js
Normal file → Executable file
@ -4,67 +4,113 @@ import { onExit } from "signal-exit"
|
|||||||
import open from "open"
|
import open from "open"
|
||||||
|
|
||||||
import SetupHelper from "./helpers/setup"
|
import SetupHelper from "./helpers/setup"
|
||||||
|
import { execa } from "./libraries/execa"
|
||||||
import Logger from "./logger"
|
import Logger from "./logger"
|
||||||
|
|
||||||
|
import Settings from "./classes/Settings"
|
||||||
import Vars from "./vars"
|
import Vars from "./vars"
|
||||||
import DB from "./db"
|
import DB from "./db"
|
||||||
|
|
||||||
import PackageInstall from "./handlers/install"
|
import PackageInstall from "./handlers/install"
|
||||||
import PackageExecute from "./handlers/execute"
|
import PackageExecute from "./handlers/execute"
|
||||||
import PackageUninstall from "./handlers/uninstall"
|
import PackageUninstall from "./handlers/uninstall"
|
||||||
|
import PackageReinstall from "./handlers/reinstall"
|
||||||
|
import PackageCancelInstall from "./handlers/cancelInstall"
|
||||||
import PackageUpdate from "./handlers/update"
|
import PackageUpdate from "./handlers/update"
|
||||||
import PackageApply from "./handlers/apply"
|
import PackageApply from "./handlers/apply"
|
||||||
import PackageList from "./handlers/list"
|
import PackageList from "./handlers/list"
|
||||||
import PackageRead from "./handlers/read"
|
import PackageRead from "./handlers/read"
|
||||||
import PackageAuthorize from "./handlers/authorize"
|
import PackageAuthorize from "./handlers/authorize"
|
||||||
|
import PackageDeauthorize from "./handlers/deauthorize"
|
||||||
import PackageCheckUpdate from "./handlers/checkUpdate"
|
import PackageCheckUpdate from "./handlers/checkUpdate"
|
||||||
import PackageLastOperationRetry from "./handlers/lastOperationRetry"
|
import PackageLastOperationRetry from "./handlers/lastOperationRetry"
|
||||||
|
|
||||||
export default class RelicCore {
|
export default class RelicCore {
|
||||||
constructor(params) {
|
constructor(params) {
|
||||||
this.params = params
|
this.params = params
|
||||||
}
|
}
|
||||||
|
|
||||||
eventBus = global._relic_eventBus = new EventEmitter()
|
eventBus = (global._relic_eventBus = new EventEmitter())
|
||||||
|
|
||||||
logger = Logger
|
logger = Logger
|
||||||
|
|
||||||
db = DB
|
db = DB
|
||||||
|
|
||||||
async initialize() {
|
async initialize() {
|
||||||
await DB.initialize()
|
globalThis.relic_core = {
|
||||||
|
tasks: [],
|
||||||
|
vars: Vars,
|
||||||
|
}
|
||||||
|
|
||||||
onExit(this.onExit)
|
console.log(`Checking runtime_path >`, Vars.runtime_path)
|
||||||
}
|
|
||||||
|
|
||||||
onExit = () => {
|
if (!fs.existsSync(Vars.runtime_path)) {
|
||||||
if (fs.existsSync(Vars.cache_path)) {
|
fs.mkdirSync(Vars.runtime_path, { recursive: true })
|
||||||
fs.rmSync(Vars.cache_path, { recursive: true, force: true })
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async setup() {
|
await DB.initialize()
|
||||||
return await SetupHelper()
|
|
||||||
}
|
|
||||||
|
|
||||||
package = {
|
await Settings.initialize()
|
||||||
install: PackageInstall,
|
|
||||||
execute: PackageExecute,
|
|
||||||
uninstall: PackageUninstall,
|
|
||||||
update: PackageUpdate,
|
|
||||||
apply: PackageApply,
|
|
||||||
list: PackageList,
|
|
||||||
read: PackageRead,
|
|
||||||
authorize: PackageAuthorize,
|
|
||||||
checkUpdate: PackageCheckUpdate,
|
|
||||||
lastOperationRetry: PackageLastOperationRetry,
|
|
||||||
}
|
|
||||||
|
|
||||||
openPath(pkg_id) {
|
if (!(await Settings.get("packages_path"))) {
|
||||||
if (!pkg_id) {
|
await Settings.set("packages_path", Vars.packages_path)
|
||||||
return open(Vars.runtime_path)
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return open(Vars.packages_path + "/" + pkg_id)
|
this.aria2c_instance = execa(
|
||||||
}
|
Vars.aria2_bin,
|
||||||
|
[
|
||||||
|
"--enable-rpc",
|
||||||
|
"--rpc-listen-all=true",
|
||||||
|
"--rpc-allow-origin-all",
|
||||||
|
"--file-allocation=none",
|
||||||
|
],
|
||||||
|
{
|
||||||
|
stdout: "inherit",
|
||||||
|
stderr: "inherit",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
onExit(this.onExit)
|
||||||
|
}
|
||||||
|
|
||||||
|
onExit = () => {
|
||||||
|
if (fs.existsSync(Vars.cache_path)) {
|
||||||
|
fs.rmSync(Vars.cache_path, { recursive: true, force: true })
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.aria2c_instance) {
|
||||||
|
this.aria2c_instance.kill("SIGINT")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async setup() {
|
||||||
|
return await SetupHelper()
|
||||||
|
}
|
||||||
|
|
||||||
|
package = {
|
||||||
|
install: PackageInstall,
|
||||||
|
execute: PackageExecute,
|
||||||
|
uninstall: PackageUninstall,
|
||||||
|
reinstall: PackageReinstall,
|
||||||
|
cancelInstall: PackageCancelInstall,
|
||||||
|
update: PackageUpdate,
|
||||||
|
apply: PackageApply,
|
||||||
|
list: PackageList,
|
||||||
|
read: PackageRead,
|
||||||
|
authorize: PackageAuthorize,
|
||||||
|
deauthorize: PackageDeauthorize,
|
||||||
|
checkUpdate: PackageCheckUpdate,
|
||||||
|
lastOperationRetry: PackageLastOperationRetry,
|
||||||
|
}
|
||||||
|
|
||||||
|
async openPath(pkg_id) {
|
||||||
|
if (!pkg_id) {
|
||||||
|
return open(Vars.runtime_path)
|
||||||
|
}
|
||||||
|
|
||||||
|
const packagesPath =
|
||||||
|
(await Settings.get("packages_path")) ?? Vars.packages_path
|
||||||
|
|
||||||
|
return open(packagesPath + "/" + pkg_id)
|
||||||
|
}
|
||||||
}
|
}
|
0
packages/core/src/libraries/execa/index.js
Normal file → Executable file
0
packages/core/src/libraries/execa/index.js
Normal file → Executable file
0
packages/core/src/libraries/execa/lib/command.js
Normal file → Executable file
0
packages/core/src/libraries/execa/lib/command.js
Normal file → Executable file
0
packages/core/src/libraries/execa/lib/error.js
Normal file → Executable file
0
packages/core/src/libraries/execa/lib/error.js
Normal file → Executable file
0
packages/core/src/libraries/execa/lib/kill.js
Normal file → Executable file
0
packages/core/src/libraries/execa/lib/kill.js
Normal file → Executable file
0
packages/core/src/libraries/execa/lib/pipe.js
Normal file → Executable file
0
packages/core/src/libraries/execa/lib/pipe.js
Normal file → Executable file
0
packages/core/src/libraries/execa/lib/promise.js
Normal file → Executable file
0
packages/core/src/libraries/execa/lib/promise.js
Normal file → Executable file
0
packages/core/src/libraries/execa/lib/stdio.js
Normal file → Executable file
0
packages/core/src/libraries/execa/lib/stdio.js
Normal file → Executable file
0
packages/core/src/libraries/execa/lib/stream.js
Normal file → Executable file
0
packages/core/src/libraries/execa/lib/stream.js
Normal file → Executable file
0
packages/core/src/libraries/execa/lib/verbose.js
Normal file → Executable file
0
packages/core/src/libraries/execa/lib/verbose.js
Normal file → Executable file
0
packages/core/src/libraries/get-stream/array-buffer.js
Normal file → Executable file
0
packages/core/src/libraries/get-stream/array-buffer.js
Normal file → Executable file
0
packages/core/src/libraries/get-stream/array.js
Normal file → Executable file
0
packages/core/src/libraries/get-stream/array.js
Normal file → Executable file
0
packages/core/src/libraries/get-stream/buffer.js
Normal file → Executable file
0
packages/core/src/libraries/get-stream/buffer.js
Normal file → Executable file
0
packages/core/src/libraries/get-stream/contents.js
Normal file → Executable file
0
packages/core/src/libraries/get-stream/contents.js
Normal file → Executable file
0
packages/core/src/libraries/get-stream/index.js
Normal file → Executable file
0
packages/core/src/libraries/get-stream/index.js
Normal file → Executable file
0
packages/core/src/libraries/get-stream/string.js
Normal file → Executable file
0
packages/core/src/libraries/get-stream/string.js
Normal file → Executable file
0
packages/core/src/libraries/get-stream/utils.js
Normal file → Executable file
0
packages/core/src/libraries/get-stream/utils.js
Normal file → Executable file
0
packages/core/src/libraries/human-signals/core.js
Normal file → Executable file
0
packages/core/src/libraries/human-signals/core.js
Normal file → Executable file
0
packages/core/src/libraries/human-signals/index.js
Normal file → Executable file
0
packages/core/src/libraries/human-signals/index.js
Normal file → Executable file
0
packages/core/src/libraries/human-signals/realtime.js
Normal file → Executable file
0
packages/core/src/libraries/human-signals/realtime.js
Normal file → Executable file
0
packages/core/src/libraries/human-signals/signals.js
Normal file → Executable file
0
packages/core/src/libraries/human-signals/signals.js
Normal file → Executable file
0
packages/core/src/libraries/is-stream/index.js
Normal file → Executable file
0
packages/core/src/libraries/is-stream/index.js
Normal file → Executable file
0
packages/core/src/libraries/lowdb/adapters/Memory.js
Normal file → Executable file
0
packages/core/src/libraries/lowdb/adapters/Memory.js
Normal file → Executable file
0
packages/core/src/libraries/lowdb/adapters/node/DataFile.js
Normal file → Executable file
0
packages/core/src/libraries/lowdb/adapters/node/DataFile.js
Normal file → Executable file
0
packages/core/src/libraries/lowdb/adapters/node/JSONFile.js
Normal file → Executable file
0
packages/core/src/libraries/lowdb/adapters/node/JSONFile.js
Normal file → Executable file
0
packages/core/src/libraries/lowdb/adapters/node/TextFile.js
Normal file → Executable file
0
packages/core/src/libraries/lowdb/adapters/node/TextFile.js
Normal file → Executable file
0
packages/core/src/libraries/lowdb/core/Low.js
Normal file → Executable file
0
packages/core/src/libraries/lowdb/core/Low.js
Normal file → Executable file
0
packages/core/src/libraries/lowdb/presets/node.js
Normal file → Executable file
0
packages/core/src/libraries/lowdb/presets/node.js
Normal file → Executable file
0
packages/core/src/libraries/lowdb/steno/index.js
Normal file → Executable file
0
packages/core/src/libraries/lowdb/steno/index.js
Normal file → Executable file
0
packages/core/src/libraries/mimic-function/index.js
Normal file → Executable file
0
packages/core/src/libraries/mimic-function/index.js
Normal file → Executable file
0
packages/core/src/libraries/npm-run-path/index.js
Normal file → Executable file
0
packages/core/src/libraries/npm-run-path/index.js
Normal file → Executable file
0
packages/core/src/libraries/onetime/index.js
Normal file → Executable file
0
packages/core/src/libraries/onetime/index.js
Normal file → Executable file
0
packages/core/src/libraries/strip-final-newline/index.js
Normal file → Executable file
0
packages/core/src/libraries/strip-final-newline/index.js
Normal file → Executable file
0
packages/core/src/logger.js
Normal file → Executable file
0
packages/core/src/logger.js
Normal file → Executable file
0
packages/core/src/manifest/libraries.js
Normal file → Executable file
0
packages/core/src/manifest/libraries.js
Normal file → Executable file
15
packages/core/src/manifest/libs/auth/index.js
Normal file → Executable file
15
packages/core/src/manifest/libs/auth/index.js
Normal file → Executable file
@ -1,6 +1,7 @@
|
|||||||
import open from "open"
|
import open from "open"
|
||||||
import axios from "axios"
|
import axios from "axios"
|
||||||
import ManifestAuthDB from "../../../classes/ManifestAuthDB"
|
import ManifestAuthDB from "../../../classes/ManifestAuthDB"
|
||||||
|
import UnauthorizeMethod from "../../../handlers/deauthorize"
|
||||||
|
|
||||||
export default class Auth {
|
export default class Auth {
|
||||||
constructor(ctx) {
|
constructor(ctx) {
|
||||||
@ -16,17 +17,23 @@ export default class Auth {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const result = await axios({
|
const result = await axios({
|
||||||
method: "POST",
|
method: "GET",
|
||||||
url: this.manifest.authService.getter,
|
url: this.manifest.authService.getter,
|
||||||
headers: {
|
headers: {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
},
|
"Authorization": `Bearer ${storagedData}`
|
||||||
data: {
|
|
||||||
auth_data: storagedData,
|
|
||||||
}
|
}
|
||||||
}).catch((err) => {
|
}).catch((err) => {
|
||||||
global._relic_eventBus.emit("auth:getter:error", err)
|
global._relic_eventBus.emit("auth:getter:error", err)
|
||||||
|
|
||||||
|
try {
|
||||||
|
UnauthorizeMethod(this.manifest.id).then(() => {
|
||||||
|
this.request()
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error)
|
||||||
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
|
|
||||||
|
34
packages/core/src/manifest/libs/extract/index.js
Executable file
34
packages/core/src/manifest/libs/extract/index.js
Executable file
@ -0,0 +1,34 @@
|
|||||||
|
import extractFile from "../../../utils/extractFile"
|
||||||
|
import { execa } from "../../../libraries/execa"
|
||||||
|
import Vars from "../../../vars"
|
||||||
|
|
||||||
|
export default class Extract {
|
||||||
|
async extractFull(file, dest, { password } = {}) {
|
||||||
|
const args = [
|
||||||
|
"x",
|
||||||
|
"-y",
|
||||||
|
]
|
||||||
|
|
||||||
|
if (password) {
|
||||||
|
args.push(`-p"${password}"`)
|
||||||
|
}
|
||||||
|
|
||||||
|
args.push(`-o"${dest}"`)
|
||||||
|
|
||||||
|
args.push(`"${file}"`)
|
||||||
|
|
||||||
|
const cmd = `${Vars.sevenzip_bin} ${args.join(" ")}`
|
||||||
|
|
||||||
|
console.log(cmd)
|
||||||
|
|
||||||
|
await execa(cmd, {
|
||||||
|
shell: true,
|
||||||
|
stdout: "inherit",
|
||||||
|
stderr: "inherit",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async autoExtract(file, dest) {
|
||||||
|
return await extractFile(file, dest)
|
||||||
|
}
|
||||||
|
}
|
36
packages/core/src/manifest/libs/fs/index.js
Normal file → Executable file
36
packages/core/src/manifest/libs/fs/index.js
Normal file → Executable file
@ -16,7 +16,7 @@ export default class SecureFileSystem {
|
|||||||
readFileSync(destination, options) {
|
readFileSync(destination, options) {
|
||||||
this.checkOutsideJail(destination)
|
this.checkOutsideJail(destination)
|
||||||
|
|
||||||
return fs.readFileSync(finalPath, options)
|
return fs.readFileSync(destination, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
copyFileSync(from, to) {
|
copyFileSync(from, to) {
|
||||||
@ -29,11 +29,43 @@ export default class SecureFileSystem {
|
|||||||
writeFileSync(destination, data, options) {
|
writeFileSync(destination, data, options) {
|
||||||
this.checkOutsideJail(destination)
|
this.checkOutsideJail(destination)
|
||||||
|
|
||||||
return fs.writeFileSync(finalPath, data, options)
|
return fs.writeFileSync(destination, data, options)
|
||||||
}
|
}
|
||||||
|
|
||||||
// don't need to check finalPath
|
// don't need to check finalPath
|
||||||
existsSync(...args) {
|
existsSync(...args) {
|
||||||
return fs.existsSync(...args)
|
return fs.existsSync(...args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async rename(from, to) {
|
||||||
|
this.checkOutsideJail(from)
|
||||||
|
this.checkOutsideJail(to)
|
||||||
|
|
||||||
|
return await fs.promises.rename(from, to)
|
||||||
|
}
|
||||||
|
|
||||||
|
async writeFile(path, data, options) {
|
||||||
|
this.checkOutsideJail(path)
|
||||||
|
return await fs.promises.writeFile(path, data, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
async readDir(path) {
|
||||||
|
this.checkOutsideJail(path)
|
||||||
|
return await fs.promises.readdir(path)
|
||||||
|
}
|
||||||
|
|
||||||
|
async rm(path, options) {
|
||||||
|
this.checkOutsideJail(path)
|
||||||
|
return await fs.promises.rm(path, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
async mkdir(path, options) {
|
||||||
|
this.checkOutsideJail(path)
|
||||||
|
return await fs.promises.mkdir(path, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
async stat(path) {
|
||||||
|
this.checkOutsideJail(path)
|
||||||
|
return await fs.promises.stat(path)
|
||||||
|
}
|
||||||
}
|
}
|
4
packages/core/src/manifest/libs/index.js
Normal file → Executable file
4
packages/core/src/manifest/libs/index.js
Normal file → Executable file
@ -2,6 +2,7 @@ import Open from "./open"
|
|||||||
import Path from "./path"
|
import Path from "./path"
|
||||||
import Fs from "./fs"
|
import Fs from "./fs"
|
||||||
import Auth from "./auth"
|
import Auth from "./auth"
|
||||||
|
import Extract from "./extract"
|
||||||
|
|
||||||
// Third party libraries
|
// Third party libraries
|
||||||
import Mcl from "./mcl"
|
import Mcl from "./mcl"
|
||||||
@ -11,5 +12,6 @@ export default {
|
|||||||
path: Path,
|
path: Path,
|
||||||
open: Open,
|
open: Open,
|
||||||
auth: Auth,
|
auth: Auth,
|
||||||
mcl: Mcl
|
extract: Extract,
|
||||||
|
mcl: Mcl,
|
||||||
}
|
}
|
4
packages/core/src/manifest/libs/mcl/authenticator.js
Normal file → Executable file
4
packages/core/src/manifest/libs/mcl/authenticator.js
Normal file → Executable file
@ -1,5 +1,5 @@
|
|||||||
const request = require('request')
|
import request from "request"
|
||||||
const { v3 } = require('uuid')
|
import {v3} from "uuid"
|
||||||
|
|
||||||
let uuid
|
let uuid
|
||||||
let api_url = 'https://authserver.mojang.com'
|
let api_url = 'https://authserver.mojang.com'
|
||||||
|
12
packages/core/src/manifest/libs/mcl/handler.js
Normal file → Executable file
12
packages/core/src/manifest/libs/mcl/handler.js
Normal file → Executable file
@ -1,9 +1,9 @@
|
|||||||
const fs = require('fs')
|
import fs from "node:fs"
|
||||||
const path = require('path')
|
import path from "node:path"
|
||||||
const request = require('request')
|
import child from "node:child_process"
|
||||||
const checksum = require('checksum')
|
import request from "request"
|
||||||
const Zip = require('adm-zip')
|
import checksum from "checksum"
|
||||||
const child = require('child_process')
|
import Zip from "adm-zip"
|
||||||
let counter = 0
|
let counter = 0
|
||||||
|
|
||||||
export default class Handler {
|
export default class Handler {
|
||||||
|
0
packages/core/src/manifest/libs/mcl/index.js
Normal file → Executable file
0
packages/core/src/manifest/libs/mcl/index.js
Normal file → Executable file
0
packages/core/src/manifest/libs/mcl/launcher.js
Normal file → Executable file
0
packages/core/src/manifest/libs/mcl/launcher.js
Normal file → Executable file
3
packages/core/src/manifest/libs/open/index.js
Normal file → Executable file
3
packages/core/src/manifest/libs/open/index.js
Normal file → Executable file
@ -6,8 +6,7 @@ const Log = Logger.child({ service: "OPEN-LIB" })
|
|||||||
|
|
||||||
export default {
|
export default {
|
||||||
spawn: async (...args) => {
|
spawn: async (...args) => {
|
||||||
Log.info("Open spawned with args >")
|
Log.info("Spawning with args >", args)
|
||||||
console.log(...args)
|
|
||||||
|
|
||||||
return await open(...args)
|
return await open(...args)
|
||||||
},
|
},
|
||||||
|
0
packages/core/src/manifest/libs/path/index.js
Normal file → Executable file
0
packages/core/src/manifest/libs/path/index.js
Normal file → Executable file
8
packages/core/src/manifest/reader.js
Normal file → Executable file
8
packages/core/src/manifest/reader.js
Normal file → Executable file
@ -11,11 +11,11 @@ export async function readManifest(manifest) {
|
|||||||
|
|
||||||
const target = manifest?.remote_url ?? manifest
|
const target = manifest?.remote_url ?? manifest
|
||||||
|
|
||||||
if (urlRegex.test(target)) {
|
if (!fs.existsSync(Vars.cache_path)) {
|
||||||
if (!fs.existsSync(Vars.cache_path)) {
|
fs.mkdirSync(Vars.cache_path, { recursive: true })
|
||||||
fs.mkdirSync(Vars.cache_path, { recursive: true })
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
if (urlRegex.test(target)) {
|
||||||
const { data: code } = await axios.get(target)
|
const { data: code } = await axios.get(target)
|
||||||
|
|
||||||
const manifestChecksum = checksum(code, { algorithm: "md5" })
|
const manifestChecksum = checksum(code, { algorithm: "md5" })
|
||||||
|
20
packages/core/src/manifest/vm.js
Normal file → Executable file
20
packages/core/src/manifest/vm.js
Normal file → Executable file
@ -3,16 +3,32 @@ import Logger from "../logger"
|
|||||||
import os from "node:os"
|
import os from "node:os"
|
||||||
import vm from "node:vm"
|
import vm from "node:vm"
|
||||||
import path from "node:path"
|
import path from "node:path"
|
||||||
|
|
||||||
|
import DB from "../db"
|
||||||
import ManifestConfigManager from "../classes/ManifestConfig"
|
import ManifestConfigManager from "../classes/ManifestConfig"
|
||||||
|
|
||||||
import resolveOs from "../utils/resolveOs"
|
import resolveOs from "../utils/resolveOs"
|
||||||
import FetchLibraries from "./libraries"
|
import FetchLibraries from "./libraries"
|
||||||
|
|
||||||
|
import Settings from "../classes/Settings"
|
||||||
|
|
||||||
import Vars from "../vars"
|
import Vars from "../vars"
|
||||||
|
|
||||||
async function BuildManifest(baseClass, context, { soft = false } = {}) {
|
async function BuildManifest(baseClass, context, { soft = false } = {}) {
|
||||||
// inject install_path
|
// try to find install_path on db
|
||||||
context.install_path = path.resolve(Vars.packages_path, baseClass.id)
|
const pkg = await DB.getPackages(baseClass.id)
|
||||||
|
|
||||||
|
if (pkg) {
|
||||||
|
if (pkg.install_path) {
|
||||||
|
context.install_path = pkg.install_path
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const packagesPath = await Settings.get("packages_path") ?? Vars.packages_path
|
||||||
|
|
||||||
|
// inject install_path
|
||||||
|
context.install_path = path.resolve(packagesPath, baseClass.id)
|
||||||
|
}
|
||||||
|
|
||||||
baseClass.install_path = context.install_path
|
baseClass.install_path = context.install_path
|
||||||
|
|
||||||
if (soft === true) {
|
if (soft === true) {
|
||||||
|
25
packages/core/src/prerequisites.js
Normal file → Executable file
25
packages/core/src/prerequisites.js
Normal file → Executable file
@ -9,9 +9,11 @@ export default [
|
|||||||
{
|
{
|
||||||
id: "7z-bin",
|
id: "7z-bin",
|
||||||
finalBin: Vars.sevenzip_bin,
|
finalBin: Vars.sevenzip_bin,
|
||||||
url: resolveRemoteBinPath(`${baseURL}/7zip-bin`, process.platform === "win32" ? "7za.exe" : "7za"),
|
url: resolveRemoteBinPath(`${baseURL}/7z-full`, "7z.zip"),
|
||||||
destination: Vars.sevenzip_bin,
|
destination: path.resolve(Vars.binaries_path, "7z.zip"),
|
||||||
|
extract: path.resolve(Vars.binaries_path, "7z-bin"),
|
||||||
rewriteExecutionPermission: true,
|
rewriteExecutionPermission: true,
|
||||||
|
deleteBeforeExtract: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "git-bin",
|
id: "git-bin",
|
||||||
@ -24,14 +26,13 @@ export default [
|
|||||||
deleteBeforeExtract: true,
|
deleteBeforeExtract: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "rclone-bin",
|
id: "aria2",
|
||||||
finalBin: Vars.rclone_bin,
|
finalBin: Vars.aria2_bin,
|
||||||
url: resolveRemoteBinPath(`${baseURL}/rclone`, "rclone-bin.zip"),
|
url: async (os, arch) => {
|
||||||
destination: path.resolve(Vars.binaries_path, "rclone-bin.zip"),
|
return `https://storage.ragestudio.net/rstudio/binaries/aria2/${os}/${arch}/${os === "win32" ? "aria2c.exe" : "aria2c"}`
|
||||||
extract: path.resolve(Vars.binaries_path, "rclone-bin"),
|
},
|
||||||
requireOs: ["win32"],
|
destination: Vars.aria2_bin,
|
||||||
rewriteExecutionPermission: true,
|
rewriteExecutionPermission: Vars.aria2_bin,
|
||||||
deleteBeforeExtract: true,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: "java22_jre_bin",
|
id: "java22_jre_bin",
|
||||||
@ -43,7 +44,7 @@ export default [
|
|||||||
params: {
|
params: {
|
||||||
arch: arch,
|
arch: arch,
|
||||||
java_version: "22",
|
java_version: "22",
|
||||||
os: os,
|
os: os === "win32" ? "windows" : os,
|
||||||
archive_type: "zip",
|
archive_type: "zip",
|
||||||
javafx_bundled: "false",
|
javafx_bundled: "false",
|
||||||
java_package_type: "jre",
|
java_package_type: "jre",
|
||||||
@ -77,7 +78,7 @@ export default [
|
|||||||
params: {
|
params: {
|
||||||
arch: arch,
|
arch: arch,
|
||||||
java_version: "17",
|
java_version: "17",
|
||||||
os: os,
|
os: os === "win32" ? "windows" : os,
|
||||||
archive_type: "zip",
|
archive_type: "zip",
|
||||||
javafx_bundled: "false",
|
javafx_bundled: "false",
|
||||||
java_package_type: "jre",
|
java_package_type: "jre",
|
||||||
|
0
packages/core/src/utils/chmodRecursive.js
Normal file → Executable file
0
packages/core/src/utils/chmodRecursive.js
Normal file → Executable file
0
packages/core/src/utils/extractFile.js
Normal file → Executable file
0
packages/core/src/utils/extractFile.js
Normal file → Executable file
0
packages/core/src/utils/parseStringVars.js
Normal file → Executable file
0
packages/core/src/utils/parseStringVars.js
Normal file → Executable file
0
packages/core/src/utils/readDirRecurse.js
Normal file → Executable file
0
packages/core/src/utils/readDirRecurse.js
Normal file → Executable file
0
packages/core/src/utils/resolveOs.js
Normal file → Executable file
0
packages/core/src/utils/resolveOs.js
Normal file → Executable file
4
packages/core/src/utils/resolveRemoteBinPath.js
Normal file → Executable file
4
packages/core/src/utils/resolveRemoteBinPath.js
Normal file → Executable file
@ -2,10 +2,10 @@ export default (pre, post) => {
|
|||||||
let url = null
|
let url = null
|
||||||
|
|
||||||
if (process.platform === "darwin") {
|
if (process.platform === "darwin") {
|
||||||
url = `${pre}/mac/${process.arch}/${post}`
|
url = `${pre}/darwin/${process.arch}/${post}`
|
||||||
}
|
}
|
||||||
else if (process.platform === "win32") {
|
else if (process.platform === "win32") {
|
||||||
url = `${pre}/win/${process.arch}/${post}`
|
url = `${pre}/win32/${process.arch}/${post}`
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
url = `${pre}/linux/${process.arch}/${post}`
|
url = `${pre}/linux/${process.arch}/${post}`
|
||||||
|
9
packages/core/src/utils/resolveUserDataPath.js
Executable file
9
packages/core/src/utils/resolveUserDataPath.js
Executable file
@ -0,0 +1,9 @@
|
|||||||
|
import path from "node:path"
|
||||||
|
import upath from "upath"
|
||||||
|
|
||||||
|
export default () => {
|
||||||
|
return upath.normalizeSafe(path.resolve(
|
||||||
|
process.env.APPDATA ||
|
||||||
|
(process.platform == "darwin" ? process.env.HOME + "/Library/Preferences" : process.env.HOME + "/.local/share"),
|
||||||
|
))
|
||||||
|
}
|
69
packages/core/src/vars.js
Normal file → Executable file
69
packages/core/src/vars.js
Normal file → Executable file
@ -1,36 +1,67 @@
|
|||||||
import path from "node:path"
|
import path from "node:path"
|
||||||
import upath from "upath"
|
import upath from "upath"
|
||||||
|
import resolveUserDataPath from "./utils/resolveUserDataPath"
|
||||||
|
|
||||||
const isWin = process.platform.includes("win")
|
const isWin = process.platform.includes("win32")
|
||||||
const isMac = process.platform.includes("darwin")
|
const isMac = process.platform.includes("darwin")
|
||||||
|
|
||||||
const runtimeName = "rs-relic"
|
const runtimeName = "rs-relic"
|
||||||
|
|
||||||
const userdata_path = upath.normalizeSafe(path.resolve(
|
const userdata_path = resolveUserDataPath()
|
||||||
process.env.APPDATA ||
|
|
||||||
(process.platform == "darwin" ? process.env.HOME + "/Library/Preferences" : process.env.HOME + "/.local/share"),
|
|
||||||
))
|
|
||||||
const runtime_path = upath.normalizeSafe(path.join(userdata_path, runtimeName))
|
const runtime_path = upath.normalizeSafe(path.join(userdata_path, runtimeName))
|
||||||
const cache_path = upath.normalizeSafe(path.join(runtime_path, "cache"))
|
const cache_path = upath.normalizeSafe(path.join(runtime_path, "cache"))
|
||||||
const packages_path = upath.normalizeSafe(path.join(runtime_path, "packages"))
|
const packages_path = upath.normalizeSafe(path.join(runtime_path, "packages"))
|
||||||
const binaries_path = upath.normalizeSafe(path.resolve(runtime_path, "binaries"))
|
const binaries_path = upath.normalizeSafe(
|
||||||
|
path.resolve(runtime_path, "binaries"),
|
||||||
|
)
|
||||||
const db_path = upath.normalizeSafe(path.resolve(runtime_path, "db.json"))
|
const db_path = upath.normalizeSafe(path.resolve(runtime_path, "db.json"))
|
||||||
|
|
||||||
const binaries = {
|
const binaries = {
|
||||||
sevenzip_bin: upath.normalizeSafe(path.resolve(binaries_path, "7z-bin", isWin ? "7za.exe" : "7za")),
|
sevenzip_bin: upath.normalizeSafe(
|
||||||
git_bin: upath.normalizeSafe(path.resolve(binaries_path, "git-bin", "bin", isWin ? "git.exe" : "git")),
|
path.resolve(binaries_path, "7z-bin", isWin ? "7za.exe" : "7z"),
|
||||||
rclone_bin: upath.normalizeSafe(path.resolve(binaries_path, "rclone-bin", isWin ? "rclone.exe" : "rclone")),
|
),
|
||||||
java22_jre_bin: upath.normalizeSafe(path.resolve(binaries_path, "java22_jre_bin", (isMac ? "Contents/Home/bin/java" : (isWin ? "bin/java.exe" : "bin/java")))),
|
git_bin: upath.normalizeSafe(
|
||||||
java17_jre_bin: upath.normalizeSafe(path.resolve(binaries_path, "java17_jre_bin", (isMac ? "Contents/Home/bin/java" : (isWin ? "bin/java.exe" : "bin/java")))),
|
path.resolve(
|
||||||
|
binaries_path,
|
||||||
|
"git-bin",
|
||||||
|
"bin",
|
||||||
|
isWin ? "git.exe" : "git",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
aria2_bin: upath.normalizeSafe(
|
||||||
|
path.resolve(binaries_path, "aria2", isWin ? "aria2c.exe" : "aria2c"),
|
||||||
|
),
|
||||||
|
java22_jre_bin: upath.normalizeSafe(
|
||||||
|
path.resolve(
|
||||||
|
binaries_path,
|
||||||
|
"java22_jre_bin",
|
||||||
|
isMac
|
||||||
|
? "Contents/Home/bin/java"
|
||||||
|
: isWin
|
||||||
|
? "bin/java.exe"
|
||||||
|
: "bin/java",
|
||||||
|
),
|
||||||
|
),
|
||||||
|
java17_jre_bin: upath.normalizeSafe(
|
||||||
|
path.resolve(
|
||||||
|
binaries_path,
|
||||||
|
"java17_jre_bin",
|
||||||
|
isMac
|
||||||
|
? "Contents/Home/bin/java"
|
||||||
|
: isWin
|
||||||
|
? "bin/java.exe"
|
||||||
|
: "bin/java",
|
||||||
|
),
|
||||||
|
),
|
||||||
}
|
}
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
runtimeName,
|
runtimeName,
|
||||||
db_path,
|
db_path,
|
||||||
userdata_path,
|
userdata_path,
|
||||||
runtime_path,
|
runtime_path,
|
||||||
cache_path,
|
cache_path,
|
||||||
packages_path,
|
packages_path,
|
||||||
binaries_path,
|
binaries_path,
|
||||||
...binaries,
|
...binaries,
|
||||||
}
|
}
|
4
packages/gui/electron-builder.yml
Normal file → Executable file
4
packages/gui/electron-builder.yml
Normal file → Executable file
@ -26,10 +26,10 @@ dmg:
|
|||||||
linux:
|
linux:
|
||||||
target:
|
target:
|
||||||
- AppImage
|
- AppImage
|
||||||
- snap
|
|
||||||
- deb
|
- deb
|
||||||
maintainer: electronjs.org
|
maintainer: ragestudio.net
|
||||||
category: Utility
|
category: Utility
|
||||||
|
icon: resources/icon.png
|
||||||
appImage:
|
appImage:
|
||||||
artifactName: ${productName}-${version}.${ext}
|
artifactName: ${productName}-${version}.${ext}
|
||||||
npmRebuild: false
|
npmRebuild: false
|
||||||
|
0
packages/gui/electron.vite.config.js
Normal file → Executable file
0
packages/gui/electron.vite.config.js
Normal file → Executable file
107
packages/gui/package.json
Normal file → Executable file
107
packages/gui/package.json
Normal file → Executable file
@ -1,55 +1,56 @@
|
|||||||
{
|
{
|
||||||
"name": "@ragestudio/relic-gui",
|
"name": "relic-gui",
|
||||||
"version": "0.17.2",
|
"version": "0.20.3",
|
||||||
"description": "RageStudio Relic, yet another package manager.",
|
"description": "RageStudio Relic, yet another package manager.",
|
||||||
"main": "./out/main/index.js",
|
"homepage": "https://relic.ragestudio.net",
|
||||||
"author": "RageStudio",
|
"main": "./out/main/index.js",
|
||||||
"license": "MIT",
|
"author": "RageStudio",
|
||||||
"scripts": {
|
"license": "MIT",
|
||||||
"start": "electron-vite preview",
|
"scripts": {
|
||||||
"dev": "npm run build:core && electron-vite dev",
|
"start": "electron-vite preview",
|
||||||
"build": "npm run build:core && electron-vite build",
|
"dev": "npm run build:core && electron-vite dev",
|
||||||
"postinstall": "electron-builder install-app-deps",
|
"build": "npm run build:core && electron-vite build",
|
||||||
"pack:win": "electron-builder --win --config",
|
"postinstall": "electron-builder install-app-deps",
|
||||||
"pack:mac": "electron-builder --mac --config",
|
"pack:win": "electron-builder --win --config",
|
||||||
"pack:linux": "electron-builder --linux --config",
|
"pack:mac": "electron-builder --mac --config",
|
||||||
"build:win": "npm run build && npm run pack:win",
|
"pack:linux": "electron-builder --linux --config",
|
||||||
"build:mac": "npm run build && npm run pack:mac",
|
"build:win": "npm run build && npm run pack:win",
|
||||||
"build:linux": "npm run build && npm run pack:linux",
|
"build:mac": "npm run build && npm run pack:mac",
|
||||||
"build:core": "cd ../core && npm run build:swc"
|
"build:linux": "npm run build && npm run pack:linux",
|
||||||
},
|
"build:core": "cd ../core && npm run build:swc"
|
||||||
"dependencies": {
|
},
|
||||||
"@electron-toolkit/preload": "^2.0.0",
|
"dependencies": {
|
||||||
"@electron-toolkit/utils": "^2.0.0",
|
"@electron-toolkit/preload": "^2.0.0",
|
||||||
"@getstation/electron-google-oauth2": "^14.0.0",
|
"@electron-toolkit/utils": "^2.0.0",
|
||||||
"@imjs/electron-differential-updater": "^5.1.7",
|
"@getstation/electron-google-oauth2": "^14.0.0",
|
||||||
"@loadable/component": "^5.16.3",
|
"@imjs/electron-differential-updater": "^5.1.7",
|
||||||
"@ragestudio/relic-core": "^0.17.0",
|
"@loadable/component": "^5.16.3",
|
||||||
"antd": "^5.13.2",
|
"@ragestudio/relic-core": "^0.20.3",
|
||||||
"classnames": "^2.3.2",
|
"antd": "^5.13.2",
|
||||||
"electron-differential-updater": "^4.3.2",
|
"classnames": "^2.3.2",
|
||||||
"electron-is-dev": "^2.0.0",
|
"electron-differential-updater": "^4.3.2",
|
||||||
"electron-store": "^8.1.0",
|
"electron-is-dev": "^2.0.0",
|
||||||
"electron-updater": "^6.1.1",
|
"electron-store": "^8.1.0",
|
||||||
"got": "11.8.3",
|
"electron-updater": "^6.1.1",
|
||||||
"human-format": "^1.2.0",
|
"got": "11.8.3",
|
||||||
"protocol-registry": "^1.4.1",
|
"human-format": "^1.2.0",
|
||||||
"less": "^4.2.0",
|
"protocol-registry": "^1.4.1",
|
||||||
"lodash": "^4.17.21",
|
"less": "^4.2.0",
|
||||||
"react-icons": "^4.11.0",
|
"lodash": "^4.17.21",
|
||||||
"react-motion": "0.5.2",
|
"react-icons": "^4.11.0",
|
||||||
"react-router-dom": "6.6.2",
|
"react-motion": "0.5.2",
|
||||||
"react-spinners": "^0.13.8",
|
"react-router-dom": "6.6.2",
|
||||||
"react-spring": "^9.7.3"
|
"react-spinners": "^0.13.8",
|
||||||
},
|
"react-spring": "^9.7.3"
|
||||||
"devDependencies": {
|
},
|
||||||
"@ragestudio/hermes": "^0.1.1",
|
"devDependencies": {
|
||||||
"@vitejs/plugin-react": "^4.0.4",
|
"@ragestudio/hermes": "^0.1.1",
|
||||||
"electron": "25.6.0",
|
"@vitejs/plugin-react": "^4.0.4",
|
||||||
"electron-builder": "24.6.3",
|
"electron": "25.6.0",
|
||||||
"electron-vite": "^2.1.0",
|
"electron-builder": "24.6.3",
|
||||||
"react": "^18.2.0",
|
"electron-vite": "^2.1.0",
|
||||||
"react-dom": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"vite": "^4.4.9"
|
"react-dom": "^18.2.0",
|
||||||
}
|
"vite": "^4.4.9"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
0
packages/gui/resources/icon.ico
Normal file → Executable file
0
packages/gui/resources/icon.ico
Normal file → Executable file
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Binary file not shown.
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 14 KiB |
0
packages/gui/resources/icon.svg
Normal file → Executable file
0
packages/gui/resources/icon.svg
Normal file → Executable file
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
57
packages/gui/src/main/classes/CoreAdapter.js
Normal file → Executable file
57
packages/gui/src/main/classes/CoreAdapter.js
Normal file → Executable file
@ -1,5 +1,6 @@
|
|||||||
import sendToRender from "../utils/sendToRender"
|
import sendToRender from "../utils/sendToRender"
|
||||||
import { ipcMain } from "electron"
|
import { ipcMain, dialog } from "electron"
|
||||||
|
import path from "node:path"
|
||||||
|
|
||||||
export default class CoreAdapter {
|
export default class CoreAdapter {
|
||||||
constructor(electronApp, RelicCore) {
|
constructor(electronApp, RelicCore) {
|
||||||
@ -44,6 +45,12 @@ export default class CoreAdapter {
|
|||||||
"pkg:uninstall": async (event, pkg_id) => {
|
"pkg:uninstall": async (event, pkg_id) => {
|
||||||
return await this.core.package.uninstall(pkg_id)
|
return await this.core.package.uninstall(pkg_id)
|
||||||
},
|
},
|
||||||
|
"pkg:reinstall": async (event, pkg_id) => {
|
||||||
|
return await this.core.package.reinstall(pkg_id)
|
||||||
|
},
|
||||||
|
"pkg:cancel_install": async (event, pkg_id) => {
|
||||||
|
return await this.core.package.cancelInstall(pkg_id)
|
||||||
|
},
|
||||||
"pkg:execute": async (event, pkg_id, { force = false } = {}) => {
|
"pkg:execute": async (event, pkg_id, { force = false } = {}) => {
|
||||||
// check for updates first
|
// check for updates first
|
||||||
if (!force) {
|
if (!force) {
|
||||||
@ -65,9 +72,34 @@ export default class CoreAdapter {
|
|||||||
"pkg:cancel_current_operation": async (event, pkg_id) => {
|
"pkg:cancel_current_operation": async (event, pkg_id) => {
|
||||||
return await this.core.package.cancelCurrentOperation(pkg_id)
|
return await this.core.package.cancelCurrentOperation(pkg_id)
|
||||||
},
|
},
|
||||||
|
"pkg:delete_auth": async (event, pkg_id) => {
|
||||||
|
return await this.core.package.deauthorize(pkg_id)
|
||||||
|
},
|
||||||
"core:open-path": async (event, pkg_id) => {
|
"core:open-path": async (event, pkg_id) => {
|
||||||
return await this.core.openPath(pkg_id)
|
return await this.core.openPath(pkg_id)
|
||||||
},
|
},
|
||||||
|
"core:change-packages-path": async (event) => {
|
||||||
|
const { canceled, filePaths } = await dialog.showOpenDialog(undefined, {
|
||||||
|
properties: ["openDirectory"]
|
||||||
|
})
|
||||||
|
|
||||||
|
if (canceled) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
const targetPath = path.resolve(filePaths[0], "RelicPackages")
|
||||||
|
|
||||||
|
await global.Settings.set("packages_path", targetPath)
|
||||||
|
|
||||||
|
return targetPath
|
||||||
|
},
|
||||||
|
"core:set-default-packages-path": async (event) => {
|
||||||
|
const { packages_path } = globalThis.relic_core.vars
|
||||||
|
|
||||||
|
await global.Settings.set("packages_path", packages_path)
|
||||||
|
|
||||||
|
return packages_path
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
coreEvents = {
|
coreEvents = {
|
||||||
@ -95,10 +127,24 @@ export default class CoreAdapter {
|
|||||||
sendToRender("app:setup", data)
|
sendToRender("app:setup", data)
|
||||||
},
|
},
|
||||||
"auth:getter:error": (err) => {
|
"auth:getter:error": (err) => {
|
||||||
|
let str = "Failed to authorize"
|
||||||
|
|
||||||
|
if (err.response.data.message) {
|
||||||
|
str = err.response.data.message
|
||||||
|
}
|
||||||
|
|
||||||
|
if (err.response.data.error) {
|
||||||
|
str = err.response.data.error
|
||||||
|
}
|
||||||
|
|
||||||
|
if (str.message) {
|
||||||
|
str = str.message
|
||||||
|
}
|
||||||
|
|
||||||
sendToRender(`new:notification`, {
|
sendToRender(`new:notification`, {
|
||||||
type: "error",
|
type: "error",
|
||||||
message: "Failed to authorize",
|
message: "Failed to authorize",
|
||||||
description: err.response.data.message ?? err.response.data.error ?? err.message,
|
description: str,
|
||||||
duration: 10
|
duration: 10
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@ -109,6 +155,13 @@ export default class CoreAdapter {
|
|||||||
description: `${pkg.name} has been authorized! You can start the package now.`,
|
description: `${pkg.name} has been authorized! You can start the package now.`,
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
"pkg:deauthorized": (pkg) => {
|
||||||
|
sendToRender(`new:notification`, {
|
||||||
|
type: "success",
|
||||||
|
message: "Package deauthorized",
|
||||||
|
description: `${pkg.name} has been deauthorized`,
|
||||||
|
})
|
||||||
|
},
|
||||||
"pkg:error": (data) => {
|
"pkg:error": (data) => {
|
||||||
sendToRender(`new:notification`, {
|
sendToRender(`new:notification`, {
|
||||||
type: "error",
|
type: "error",
|
||||||
|
26
packages/gui/src/main/index.js
Normal file → Executable file
26
packages/gui/src/main/index.js
Normal file → Executable file
@ -1,20 +1,18 @@
|
|||||||
global.SettingsStore = new Store({
|
|
||||||
name: "settings",
|
|
||||||
watch: true,
|
|
||||||
})
|
|
||||||
import path from "node:path"
|
import path from "node:path"
|
||||||
|
|
||||||
import { app, shell, BrowserWindow, ipcMain } from "electron"
|
import { app, shell, BrowserWindow, ipcMain } from "electron"
|
||||||
import { electronApp, optimizer, is } from "@electron-toolkit/utils"
|
import { electronApp, optimizer, is } from "@electron-toolkit/utils"
|
||||||
import isDev from "electron-is-dev"
|
import isDev from "electron-is-dev"
|
||||||
import Store from "electron-store"
|
|
||||||
|
|
||||||
let RelicCore = null
|
let RelicCore = null
|
||||||
|
let Settings = null
|
||||||
|
|
||||||
if (isDev) {
|
if (isDev) {
|
||||||
RelicCore = require("../../../core").default
|
RelicCore = require("../../../core/dist").default
|
||||||
|
Settings = global.Settings = require("../../../core/dist/classes/Settings").default
|
||||||
} else {
|
} else {
|
||||||
RelicCore = require("@ragestudio/relic-core").default
|
RelicCore = require("@ragestudio/relic-core").default
|
||||||
|
Settings = global.Settings = require("@ragestudio/relic-core/dist/classes/Settings").default
|
||||||
}
|
}
|
||||||
|
|
||||||
import CoreAdapter from "./classes/CoreAdapter"
|
import CoreAdapter from "./classes/CoreAdapter"
|
||||||
@ -84,17 +82,17 @@ class ElectronApp {
|
|||||||
autoUpdater.quitAndInstall()
|
autoUpdater.quitAndInstall()
|
||||||
}, 3000)
|
}, 3000)
|
||||||
},
|
},
|
||||||
"settings:get": (event, key) => {
|
"settings:get": async (event, key) => {
|
||||||
return global.SettingsStore.get(key)
|
return await Settings.get(key)
|
||||||
},
|
},
|
||||||
"settings:set": (event, key, value) => {
|
"settings:set": async (event, key, value) => {
|
||||||
return global.SettingsStore.set(key, value)
|
return await Settings.set(key, value)
|
||||||
},
|
},
|
||||||
"settings:delete": (event, key) => {
|
"settings:delete": async (event, key) => {
|
||||||
return global.SettingsStore.delete(key)
|
return await Settings.delete(key)
|
||||||
},
|
},
|
||||||
"settings:has": (event, key) => {
|
"settings:has": async (event, key) => {
|
||||||
return global.SettingsStore.has(key)
|
return await Settings.has(key)
|
||||||
},
|
},
|
||||||
"app:open-logs": async (event) => {
|
"app:open-logs": async (event) => {
|
||||||
const loggerWindow = await this.logsViewer.createWindow()
|
const loggerWindow = await this.logsViewer.createWindow()
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user