Compare commits

..

No commits in common. "main" and "v0.17.2" have entirely different histories.

149 changed files with 406 additions and 1154 deletions

0
.github/workflows/release.yml vendored Executable file → Normal file
View File

0
.gitignore vendored Executable file → Normal file
View File

4
package.json Executable file → Normal file
View File

@ -1,5 +1,9 @@
{ {
"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 Executable file → Normal file
View File

0
packages/cli/package.json Executable file → Normal file
View File

0
packages/cli/src/index.js Executable file → Normal file
View File

0
packages/core/.swcrc Executable file → Normal file
View File

84
packages/core/package.json Executable file → Normal file
View File

@ -1,45 +1,43 @@
{ {
"name": "@ragestudio/relic-core", "name": "@ragestudio/relic-core",
"version": "0.20.3", "version": "0.17.1",
"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",
"aria2": "^4.1.2", "axios": "^1.6.8",
"axios": "^1.6.8", "checksum": "^1.0.0",
"checksum": "^1.0.0", "cli-color": "^2.0.4",
"cli-color": "^2.0.4", "cli-progress": "^3.12.0",
"cli-progress": "^3.12.0", "deep-object-diff": "^1.1.9",
"deep-object-diff": "^1.1.9", "extends-classes": "^1.0.5",
"extends-classes": "^1.0.5", "googleapis": "^134.0.0",
"googleapis": "^134.0.0", "human-format": "^1.2.0",
"human-format": "^1.2.0", "merge-stream": "^2.0.0",
"merge-stream": "^2.0.0", "module-alias": "^2.2.3",
"module-alias": "^2.2.3", "node-7z": "^3.0.0",
"node-7z": "^3.0.0", "open": "8.4.2",
"open": "8.4.2", "request": "^2.88.2",
"request": "^2.88.2", "rimraf": "^5.0.5",
"rimraf": "^5.0.5", "signal-exit": "^4.1.0",
"signal-exit": "^4.1.0", "unzipper": "^0.10.14",
"unzipper": "^0.10.14", "upath": "^2.0.1",
"upath": "^2.0.1", "uuid": "^9.0.1",
"uuid": "^9.0.1", "winston": "^3.13.0"
"webtorrent": "^2.4.1", },
"winston": "^3.13.0" "devDependencies": {
}, "@swc/cli": "^0.3.12",
"devDependencies": { "@swc/core": "^1.4.11"
"@swc/cli": "^0.3.12", }
"@swc/core": "^1.4.11"
}
} }

8
packages/core/src/classes/ManifestAuthDB.js Executable file → Normal file
View File

@ -33,12 +33,4 @@ 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 Executable file → Normal file
View File

0
packages/core/src/classes/PatchManager.js Executable file → Normal file
View File

View File

@ -1,57 +0,0 @@
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 Executable file → Normal file
View File

@ -2,6 +2,7 @@ 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() {
@ -93,15 +94,11 @@ 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({ return await this.writePackage(lodash.merge({ ...pkg }, obj))
...pkg,
...obj,
})
} }
static async deletePackage(pkg_id) { static async deletePackage(pkg_id) {

2
packages/core/src/generic_steps/git_clone.js Executable file → Normal file
View 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_bin) ? `${Vars.git_bin}` : "git" const gitCMD = fs.existsSync(Vars.git_path) ? `${Vars.git_path}` : "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 Executable file → Normal file
View 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_bin) ? `${Vars.git_bin}` : "git" const gitCMD = fs.existsSync(Vars.git_path) ? `${Vars.git_path}` : "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 Executable file → Normal file
View 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_bin) ? `${Vars.git_bin}` : "git" const gitCMD = fs.existsSync(Vars.git_path) ? `${Vars.git_path}` : "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 Executable file → Normal file
View 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, abortController) => { export default async (pkg, step, logger) => {
if (!step.path) { if (!step.path) {
step.path = `./${path.basename(step.url)}` step.path = `./${path.basename(step.url)}`
} }
@ -28,18 +28,13 @@ export default async (pkg, step, logger, abortController) => {
fs.mkdirSync(path.resolve(_path, ".."), { recursive: true }) fs.mkdirSync(path.resolve(_path, ".."), { recursive: true })
await downloadHttpFile( await downloadHttpFile(step.url, _path, (progress) => {
step.url, global._relic_eventBus.emit(`pkg:update:state`, {
_path, id: pkg.id,
(progress) => { use_id_only: true,
global._relic_eventBus.emit(`pkg:update:state`, { status_text: `Downloaded ${progress.transferredString} / ${progress.totalString} | ${progress.speedString}/s`,
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 Executable file → Normal file
View File

@ -4,25 +4,22 @@ 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, abortController) { export default async function processGenericSteps(pkg, steps, logger = Logger) {
logger.info(`Processing generic steps...`) logger.info(`Processing generic steps...`)
if (!Array.isArray(steps)) { if (!Array.isArray(steps)) {
@ -40,15 +37,11 @@ export default async function processGenericSteps(pkg, steps, logger = Logger, a
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, abortController) await InstallationStepsMethods[step.type](pkg, step, logger)
} }
return pkg return pkg

View File

@ -1,48 +0,0 @@
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 Executable file → Normal file
View File

@ -59,8 +59,6 @@ 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 Executable file → Normal file
View File

View File

@ -1,44 +0,0 @@
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 Executable file → Normal file
View File

View File

@ -1,28 +0,0 @@
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 Executable file → Normal file
View File

@ -43,8 +43,6 @@ 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 Executable file → Normal file
View File

@ -10,9 +10,8 @@ import Apply from "../handlers/apply"
const BaseLog = Logger.child({ service: "INSTALLER" }) const BaseLog = Logger.child({ service: "INSTALLER" })
export default async function install(manifest, options = {}) { export default async function install(manifest) {
let id = null let id = null
let abortController = new AbortController()
try { try {
BaseLog.info(`Invoking new installation...`) BaseLog.info(`Invoking new installation...`)
@ -24,20 +23,10 @@ export default async function install(manifest, options = {}) {
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 })
@ -47,21 +36,13 @@ export default async function install(manifest, options = {}) {
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...`)
if (abortController.signal.aborted) { const pkg = DB.defaultPackageState({
return false
}
let pkg = DB.defaultPackageState({
...manifest.constructor, ...manifest.constructor,
id: id, id: id,
name: manifest.constructor.pkg_name, name: manifest.constructor.pkg_name,
@ -79,10 +60,6 @@ export default async function install(manifest, options = {}) {
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...`)
@ -93,10 +70,6 @@ export default async function install(manifest, options = {}) {
}, {}) }, {})
} }
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...`)
@ -108,11 +81,7 @@ export default async function install(manifest, options = {}) {
await manifest.beforeInstall(pkg) await manifest.beforeInstall(pkg)
} }
if (abortController.signal.aborted) { if (Array.isArray(manifest.installSteps)) {
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`, {
@ -120,11 +89,7 @@ export default async function install(manifest, options = {}) {
status_text: `Performing generic install steps...`, status_text: `Performing generic install steps...`,
}) })
await GenericSteps(pkg, manifest.installSteps, Log, abortController) await GenericSteps(pkg, manifest.installSteps, Log)
}
if (abortController.signal.aborted) {
return false
} }
if (typeof manifest.afterInstall === "function") { if (typeof manifest.afterInstall === "function") {
@ -147,10 +112,6 @@ export default async function install(manifest, options = {}) {
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)
} }
@ -168,10 +129,6 @@ export default async function install(manifest, options = {}) {
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)
@ -183,7 +140,7 @@ export default async function install(manifest, options = {}) {
status_text: `Applying default patches...`, status_text: `Applying default patches...`,
}) })
pkg = await Apply(id, { await Apply(id, {
patches: Object.fromEntries(defaultPatches.map((patch) => [patch.id, true])), patches: Object.fromEntries(defaultPatches.map((patch) => [patch.id, true])),
}) })
} }
@ -191,14 +148,8 @@ export default async function install(manifest, options = {}) {
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,
@ -224,8 +175,6 @@ export default async function install(manifest, options = {}) {
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 Executable file → Normal file
View File

0
packages/core/src/handlers/list.js Executable file → Normal file
View File

0
packages/core/src/handlers/read.js Executable file → Normal file
View File

View File

@ -1,35 +0,0 @@
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 Executable file → Normal file
View File

0
packages/core/src/handlers/update.js Executable file → Normal file
View File

3
packages/core/src/helpers/downloadHttpFile.js Executable file → Normal file
View File

@ -9,7 +9,7 @@ function convertSize(size) {
})}B` })}B`
} }
export default async (url, destination, progressCallback, abortController) => { export default async (url, destination, progressCallback) => {
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,7 +19,6 @@ export default async (url, destination, progressCallback, abortController) => {
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)

View File

@ -1,140 +0,0 @@
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 Executable file → Normal file
View File

2
packages/core/src/helpers/setup.js Executable file → Normal file
View 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(os.platform(), os.arch()) prerequisite.url = await prerequisite.url(resolveOs(), os.arch())
Log.info(`Resolved url: ${prerequisite.url}`) Log.info(`Resolved url: ${prerequisite.url}`)
} }

120
packages/core/src/index.js Executable file → Normal file
View File

@ -4,113 +4,67 @@ 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() {
globalThis.relic_core = { await DB.initialize()
tasks: [],
vars: Vars,
}
console.log(`Checking runtime_path >`, Vars.runtime_path) onExit(this.onExit)
}
if (!fs.existsSync(Vars.runtime_path)) { onExit = () => {
fs.mkdirSync(Vars.runtime_path, { recursive: true }) if (fs.existsSync(Vars.cache_path)) {
} fs.rmSync(Vars.cache_path, { recursive: true, force: true })
}
}
await DB.initialize() async setup() {
return await SetupHelper()
}
await Settings.initialize() package = {
install: PackageInstall,
execute: PackageExecute,
uninstall: PackageUninstall,
update: PackageUpdate,
apply: PackageApply,
list: PackageList,
read: PackageRead,
authorize: PackageAuthorize,
checkUpdate: PackageCheckUpdate,
lastOperationRetry: PackageLastOperationRetry,
}
if (!(await Settings.get("packages_path"))) { openPath(pkg_id) {
await Settings.set("packages_path", Vars.packages_path) if (!pkg_id) {
} return open(Vars.runtime_path)
}
this.aria2c_instance = execa( return open(Vars.packages_path + "/" + pkg_id)
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 Executable file → Normal file
View File

0
packages/core/src/libraries/execa/lib/command.js Executable file → Normal file
View File

0
packages/core/src/libraries/execa/lib/error.js Executable file → Normal file
View File

0
packages/core/src/libraries/execa/lib/kill.js Executable file → Normal file
View File

0
packages/core/src/libraries/execa/lib/pipe.js Executable file → Normal file
View File

0
packages/core/src/libraries/execa/lib/promise.js Executable file → Normal file
View File

0
packages/core/src/libraries/execa/lib/stdio.js Executable file → Normal file
View File

0
packages/core/src/libraries/execa/lib/stream.js Executable file → Normal file
View File

0
packages/core/src/libraries/execa/lib/verbose.js Executable file → Normal file
View File

0
packages/core/src/libraries/get-stream/array-buffer.js Executable file → Normal file
View File

0
packages/core/src/libraries/get-stream/array.js Executable file → Normal file
View File

0
packages/core/src/libraries/get-stream/buffer.js Executable file → Normal file
View File

0
packages/core/src/libraries/get-stream/contents.js Executable file → Normal file
View File

0
packages/core/src/libraries/get-stream/index.js Executable file → Normal file
View File

0
packages/core/src/libraries/get-stream/string.js Executable file → Normal file
View File

0
packages/core/src/libraries/get-stream/utils.js Executable file → Normal file
View File

0
packages/core/src/libraries/human-signals/core.js Executable file → Normal file
View File

0
packages/core/src/libraries/human-signals/index.js Executable file → Normal file
View File

0
packages/core/src/libraries/human-signals/realtime.js Executable file → Normal file
View File

0
packages/core/src/libraries/human-signals/signals.js Executable file → Normal file
View File

0
packages/core/src/libraries/is-stream/index.js Executable file → Normal file
View File

0
packages/core/src/libraries/lowdb/adapters/Memory.js Executable file → Normal file
View File

View File

View File

View File

0
packages/core/src/libraries/lowdb/core/Low.js Executable file → Normal file
View File

0
packages/core/src/libraries/lowdb/presets/node.js Executable file → Normal file
View File

0
packages/core/src/libraries/lowdb/steno/index.js Executable file → Normal file
View File

0
packages/core/src/libraries/mimic-function/index.js Executable file → Normal file
View File

0
packages/core/src/libraries/npm-run-path/index.js Executable file → Normal file
View File

0
packages/core/src/libraries/onetime/index.js Executable file → Normal file
View File

View File

0
packages/core/src/logger.js Executable file → Normal file
View File

0
packages/core/src/manifest/libraries.js Executable file → Normal file
View File

15
packages/core/src/manifest/libs/auth/index.js Executable file → Normal file
View File

@ -1,7 +1,6 @@
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) {
@ -17,23 +16,17 @@ export default class Auth {
} }
const result = await axios({ const result = await axios({
method: "GET", method: "POST",
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
}) })

View File

@ -1,34 +0,0 @@
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 Executable file → Normal file
View File

@ -16,7 +16,7 @@ export default class SecureFileSystem {
readFileSync(destination, options) { readFileSync(destination, options) {
this.checkOutsideJail(destination) this.checkOutsideJail(destination)
return fs.readFileSync(destination, options) return fs.readFileSync(finalPath, options)
} }
copyFileSync(from, to) { copyFileSync(from, to) {
@ -29,43 +29,11 @@ export default class SecureFileSystem {
writeFileSync(destination, data, options) { writeFileSync(destination, data, options) {
this.checkOutsideJail(destination) this.checkOutsideJail(destination)
return fs.writeFileSync(destination, data, options) return fs.writeFileSync(finalPath, 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 Executable file → Normal file
View File

@ -2,7 +2,6 @@ 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"
@ -12,6 +11,5 @@ export default {
path: Path, path: Path,
open: Open, open: Open,
auth: Auth, auth: Auth,
extract: Extract, mcl: Mcl
mcl: Mcl,
} }

4
packages/core/src/manifest/libs/mcl/authenticator.js Executable file → Normal file
View File

@ -1,5 +1,5 @@
import request from "request" const request = require('request')
import {v3} from "uuid" const { v3 } = require('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 Executable file → Normal file
View File

@ -1,9 +1,9 @@
import fs from "node:fs" const fs = require('fs')
import path from "node:path" const path = require('path')
import child from "node:child_process" const request = require('request')
import request from "request" const checksum = require('checksum')
import checksum from "checksum" const Zip = require('adm-zip')
import Zip from "adm-zip" const child = require('child_process')
let counter = 0 let counter = 0
export default class Handler { export default class Handler {

0
packages/core/src/manifest/libs/mcl/index.js Executable file → Normal file
View File

0
packages/core/src/manifest/libs/mcl/launcher.js Executable file → Normal file
View File

3
packages/core/src/manifest/libs/open/index.js Executable file → Normal file
View File

@ -6,7 +6,8 @@ const Log = Logger.child({ service: "OPEN-LIB" })
export default { export default {
spawn: async (...args) => { spawn: async (...args) => {
Log.info("Spawning with args >", args) Log.info("Open spawned with args >")
console.log(...args)
return await open(...args) return await open(...args)
}, },

0
packages/core/src/manifest/libs/path/index.js Executable file → Normal file
View File

8
packages/core/src/manifest/reader.js Executable file → Normal file
View File

@ -11,11 +11,11 @@ export async function readManifest(manifest) {
const target = manifest?.remote_url ?? manifest const target = manifest?.remote_url ?? manifest
if (!fs.existsSync(Vars.cache_path)) {
fs.mkdirSync(Vars.cache_path, { recursive: true })
}
if (urlRegex.test(target)) { if (urlRegex.test(target)) {
if (!fs.existsSync(Vars.cache_path)) {
fs.mkdirSync(Vars.cache_path, { recursive: true })
}
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 Executable file → Normal file
View File

@ -3,32 +3,16 @@ 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 } = {}) {
// try to find install_path on db // inject install_path
const pkg = await DB.getPackages(baseClass.id) context.install_path = path.resolve(Vars.packages_path, 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 Executable file → Normal file
View File

@ -9,11 +9,9 @@ export default [
{ {
id: "7z-bin", id: "7z-bin",
finalBin: Vars.sevenzip_bin, finalBin: Vars.sevenzip_bin,
url: resolveRemoteBinPath(`${baseURL}/7z-full`, "7z.zip"), url: resolveRemoteBinPath(`${baseURL}/7zip-bin`, process.platform === "win32" ? "7za.exe" : "7za"),
destination: path.resolve(Vars.binaries_path, "7z.zip"), destination: Vars.sevenzip_bin,
extract: path.resolve(Vars.binaries_path, "7z-bin"),
rewriteExecutionPermission: true, rewriteExecutionPermission: true,
deleteBeforeExtract: true,
}, },
{ {
id: "git-bin", id: "git-bin",
@ -26,13 +24,14 @@ export default [
deleteBeforeExtract: true, deleteBeforeExtract: true,
}, },
{ {
id: "aria2", id: "rclone-bin",
finalBin: Vars.aria2_bin, finalBin: Vars.rclone_bin,
url: async (os, arch) => { url: resolveRemoteBinPath(`${baseURL}/rclone`, "rclone-bin.zip"),
return `https://storage.ragestudio.net/rstudio/binaries/aria2/${os}/${arch}/${os === "win32" ? "aria2c.exe" : "aria2c"}` destination: path.resolve(Vars.binaries_path, "rclone-bin.zip"),
}, extract: path.resolve(Vars.binaries_path, "rclone-bin"),
destination: Vars.aria2_bin, requireOs: ["win32"],
rewriteExecutionPermission: Vars.aria2_bin, rewriteExecutionPermission: true,
deleteBeforeExtract: true,
}, },
{ {
id: "java22_jre_bin", id: "java22_jre_bin",
@ -44,7 +43,7 @@ export default [
params: { params: {
arch: arch, arch: arch,
java_version: "22", java_version: "22",
os: os === "win32" ? "windows" : os, os: os,
archive_type: "zip", archive_type: "zip",
javafx_bundled: "false", javafx_bundled: "false",
java_package_type: "jre", java_package_type: "jre",
@ -78,7 +77,7 @@ export default [
params: { params: {
arch: arch, arch: arch,
java_version: "17", java_version: "17",
os: os === "win32" ? "windows" : os, os: 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 Executable file → Normal file
View File

0
packages/core/src/utils/extractFile.js Executable file → Normal file
View File

0
packages/core/src/utils/parseStringVars.js Executable file → Normal file
View File

0
packages/core/src/utils/readDirRecurse.js Executable file → Normal file
View File

0
packages/core/src/utils/resolveOs.js Executable file → Normal file
View File

4
packages/core/src/utils/resolveRemoteBinPath.js Executable file → Normal file
View 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}/darwin/${process.arch}/${post}` url = `${pre}/mac/${process.arch}/${post}`
} }
else if (process.platform === "win32") { else if (process.platform === "win32") {
url = `${pre}/win32/${process.arch}/${post}` url = `${pre}/win/${process.arch}/${post}`
} }
else { else {
url = `${pre}/linux/${process.arch}/${post}` url = `${pre}/linux/${process.arch}/${post}`

View File

@ -1,9 +0,0 @@
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"),
))
}

71
packages/core/src/vars.js Executable file → Normal file
View File

@ -1,67 +1,36 @@
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("win32") const isWin = process.platform.includes("win")
const isMac = process.platform.includes("darwin") const isMac = process.platform.includes("darwin")
const runtimeName = "rs-relic" const runtimeName = "rs-relic"
const userdata_path = resolveUserDataPath() const userdata_path = upath.normalizeSafe(path.resolve(
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( const binaries_path = upath.normalizeSafe(path.resolve(runtime_path, "binaries"))
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( sevenzip_bin: upath.normalizeSafe(path.resolve(binaries_path, "7z-bin", isWin ? "7za.exe" : "7za")),
path.resolve(binaries_path, "7z-bin", isWin ? "7za.exe" : "7z"), git_bin: upath.normalizeSafe(path.resolve(binaries_path, "git-bin", "bin", isWin ? "git.exe" : "git")),
), rclone_bin: upath.normalizeSafe(path.resolve(binaries_path, "rclone-bin", isWin ? "rclone.exe" : "rclone")),
git_bin: upath.normalizeSafe( java22_jre_bin: upath.normalizeSafe(path.resolve(binaries_path, "java22_jre_bin", (isMac ? "Contents/Home/bin/java" : (isWin ? "bin/java.exe" : "bin/java")))),
path.resolve( java17_jre_bin: upath.normalizeSafe(path.resolve(binaries_path, "java17_jre_bin", (isMac ? "Contents/Home/bin/java" : (isWin ? "bin/java.exe" : "bin/java")))),
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 Executable file → Normal file
View File

@ -26,10 +26,10 @@ dmg:
linux: linux:
target: target:
- AppImage - AppImage
- snap
- deb - deb
maintainer: ragestudio.net maintainer: electronjs.org
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 Executable file → Normal file
View File

107
packages/gui/package.json Executable file → Normal file
View File

@ -1,56 +1,55 @@
{ {
"name": "relic-gui", "name": "@ragestudio/relic-gui",
"version": "0.20.3", "version": "0.17.2",
"description": "RageStudio Relic, yet another package manager.", "description": "RageStudio Relic, yet another package manager.",
"homepage": "https://relic.ragestudio.net", "main": "./out/main/index.js",
"main": "./out/main/index.js", "author": "RageStudio",
"author": "RageStudio", "license": "MIT",
"license": "MIT", "scripts": {
"scripts": { "start": "electron-vite preview",
"start": "electron-vite preview", "dev": "npm run build:core && electron-vite dev",
"dev": "npm run build:core && electron-vite dev", "build": "npm run build:core && electron-vite build",
"build": "npm run build:core && electron-vite build", "postinstall": "electron-builder install-app-deps",
"postinstall": "electron-builder install-app-deps", "pack:win": "electron-builder --win --config",
"pack:win": "electron-builder --win --config", "pack:mac": "electron-builder --mac --config",
"pack:mac": "electron-builder --mac --config", "pack:linux": "electron-builder --linux --config",
"pack:linux": "electron-builder --linux --config", "build:win": "npm run build && npm run pack:win",
"build:win": "npm run build && npm run pack:win", "build:mac": "npm run build && npm run pack:mac",
"build:mac": "npm run build && npm run pack:mac", "build:linux": "npm run build && npm run pack:linux",
"build:linux": "npm run build && npm run pack:linux", "build:core": "cd ../core && npm run build:swc"
"build:core": "cd ../core && npm run build:swc" },
}, "dependencies": {
"dependencies": { "@electron-toolkit/preload": "^2.0.0",
"@electron-toolkit/preload": "^2.0.0", "@electron-toolkit/utils": "^2.0.0",
"@electron-toolkit/utils": "^2.0.0", "@getstation/electron-google-oauth2": "^14.0.0",
"@getstation/electron-google-oauth2": "^14.0.0", "@imjs/electron-differential-updater": "^5.1.7",
"@imjs/electron-differential-updater": "^5.1.7", "@loadable/component": "^5.16.3",
"@loadable/component": "^5.16.3", "@ragestudio/relic-core": "^0.17.0",
"@ragestudio/relic-core": "^0.20.3", "antd": "^5.13.2",
"antd": "^5.13.2", "classnames": "^2.3.2",
"classnames": "^2.3.2", "electron-differential-updater": "^4.3.2",
"electron-differential-updater": "^4.3.2", "electron-is-dev": "^2.0.0",
"electron-is-dev": "^2.0.0", "electron-store": "^8.1.0",
"electron-store": "^8.1.0", "electron-updater": "^6.1.1",
"electron-updater": "^6.1.1", "got": "11.8.3",
"got": "11.8.3", "human-format": "^1.2.0",
"human-format": "^1.2.0", "protocol-registry": "^1.4.1",
"protocol-registry": "^1.4.1", "less": "^4.2.0",
"less": "^4.2.0", "lodash": "^4.17.21",
"lodash": "^4.17.21", "react-icons": "^4.11.0",
"react-icons": "^4.11.0", "react-motion": "0.5.2",
"react-motion": "0.5.2", "react-router-dom": "6.6.2",
"react-router-dom": "6.6.2", "react-spinners": "^0.13.8",
"react-spinners": "^0.13.8", "react-spring": "^9.7.3"
"react-spring": "^9.7.3" },
}, "devDependencies": {
"devDependencies": { "@ragestudio/hermes": "^0.1.1",
"@ragestudio/hermes": "^0.1.1", "@vitejs/plugin-react": "^4.0.4",
"@vitejs/plugin-react": "^4.0.4", "electron": "25.6.0",
"electron": "25.6.0", "electron-builder": "24.6.3",
"electron-builder": "24.6.3", "electron-vite": "^2.1.0",
"electron-vite": "^2.1.0", "react": "^18.2.0",
"react": "^18.2.0", "react-dom": "^18.2.0",
"react-dom": "^18.2.0", "vite": "^4.4.9"
"vite": "^4.4.9" }
}
} }

0
packages/gui/resources/icon.ico Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 28 KiB

0
packages/gui/resources/icon.svg Executable file → Normal file
View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

57
packages/gui/src/main/classes/CoreAdapter.js Executable file → Normal file
View File

@ -1,6 +1,5 @@
import sendToRender from "../utils/sendToRender" import sendToRender from "../utils/sendToRender"
import { ipcMain, dialog } from "electron" import { ipcMain } from "electron"
import path from "node:path"
export default class CoreAdapter { export default class CoreAdapter {
constructor(electronApp, RelicCore) { constructor(electronApp, RelicCore) {
@ -45,12 +44,6 @@ 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) {
@ -72,34 +65,9 @@ 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 = {
@ -127,24 +95,10 @@ 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: str, description: err.response.data.message ?? err.response.data.error ?? err.message,
duration: 10 duration: 10
}) })
}, },
@ -155,13 +109,6 @@ 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 Executable file → Normal file
View File

@ -1,18 +1,20 @@
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/dist").default RelicCore = require("../../../core").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"
@ -82,17 +84,17 @@ class ElectronApp {
autoUpdater.quitAndInstall() autoUpdater.quitAndInstall()
}, 3000) }, 3000)
}, },
"settings:get": async (event, key) => { "settings:get": (event, key) => {
return await Settings.get(key) return global.SettingsStore.get(key)
}, },
"settings:set": async (event, key, value) => { "settings:set": (event, key, value) => {
return await Settings.set(key, value) return global.SettingsStore.set(key, value)
}, },
"settings:delete": async (event, key) => { "settings:delete": (event, key) => {
return await Settings.delete(key) return global.SettingsStore.delete(key)
}, },
"settings:has": async (event, key) => { "settings:has": (event, key) => {
return await Settings.has(key) return global.SettingsStore.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