212 lines
5.4 KiB
JavaScript
212 lines
5.4 KiB
JavaScript
/**
|
|
* BetterDiscord Utils Module
|
|
* Copyright (c) 2015-present JsSucks - https://github.com/JsSucks
|
|
* All rights reserved.
|
|
* https://github.com/JsSucks - https://betterdiscord.net
|
|
*
|
|
* This source code is licensed under the MIT license found in the
|
|
* LICENSE file in the root directory of this source tree.
|
|
*/
|
|
|
|
// TODO Use common
|
|
|
|
const path = require('path');
|
|
const fs = require('fs');
|
|
|
|
const { Module } = require('./modulebase');
|
|
|
|
class Utils {
|
|
static async tryParseJson(jsonString) {
|
|
try {
|
|
return JSON.parse(jsonString);
|
|
} catch (err) {
|
|
throw ({
|
|
message: 'Failed to parse json',
|
|
err
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
class FileUtils {
|
|
static async fileExists(path) {
|
|
return new Promise((resolve, reject) => {
|
|
fs.stat(path, (err, stats) => {
|
|
if(err) return reject({
|
|
message: `No such file or directory: ${err.path}`,
|
|
err
|
|
});
|
|
|
|
if(!stats.isFile()) return reject({
|
|
message: `Not a file: ${path}`,
|
|
stats
|
|
});
|
|
|
|
resolve();
|
|
});
|
|
});
|
|
}
|
|
|
|
static async directoryExists(path) {
|
|
return new Promise((resolve, reject) => {
|
|
fs.stat(path, (err, stats) => {
|
|
if(err) return reject({
|
|
message: `Directory does not exist: ${path}`,
|
|
err
|
|
});
|
|
|
|
if(!stats.isDirectory()) return reject({
|
|
message: `Not a directory: ${path}`,
|
|
stats
|
|
});
|
|
|
|
resolve();
|
|
});
|
|
});
|
|
}
|
|
|
|
static async readFile(path) {
|
|
try {
|
|
await this.fileExists(path);
|
|
} catch (err) {
|
|
throw err;
|
|
}
|
|
|
|
return new Promise((resolve, reject) => {
|
|
fs.readFile(path, 'utf-8', (err, data) => {
|
|
if(err) return reject({
|
|
message: `Could not read file: ${path}`,
|
|
err
|
|
});
|
|
|
|
resolve(data);
|
|
});
|
|
});
|
|
}
|
|
|
|
static async readJsonFromFile(path) {
|
|
let readFile;
|
|
try {
|
|
readFile = await this.readFile(path);
|
|
} catch(err) {
|
|
throw err;
|
|
}
|
|
|
|
try {
|
|
return await Utils.tryParseJson(readFile);
|
|
} catch (err) {
|
|
throw Object.assign(err, { path });
|
|
}
|
|
}
|
|
|
|
static async listDirectory(path) {
|
|
try {
|
|
await this.directoryExists(path);
|
|
return new Promise((resolve, reject) => {
|
|
fs.readdir(path, (err, files) => {
|
|
if (err) reject(err);
|
|
else resolve(files);
|
|
});
|
|
});
|
|
} catch (err) {
|
|
throw err;
|
|
}
|
|
}
|
|
|
|
static filterFiles(files, filter, map) {
|
|
if (!map) return files.filter(filter);
|
|
return files.filter(filter).map(map);
|
|
}
|
|
|
|
static resolveLatest(files, filter, map, prefix, suffix) {
|
|
let latest = null;
|
|
for (const file of this.filterFiles(files, filter, map)) {
|
|
const [major, minor, revision] = file.split('.');
|
|
if (!major || !minor || !revision) continue;
|
|
if (!latest) {
|
|
latest = file;
|
|
continue;
|
|
}
|
|
|
|
latest = file > latest ? file : latest;
|
|
}
|
|
return (prefix && suffix) ? `${prefix}${latest}${suffix}` : latest;
|
|
}
|
|
|
|
static async createDirectory(path) {
|
|
return new Promise((resolve, reject) => {
|
|
fs.mkdir(path, err => {
|
|
if (err) reject(err);
|
|
else resolve();
|
|
});
|
|
});
|
|
}
|
|
|
|
static async ensureDirectory(path) {
|
|
try {
|
|
await this.directoryExists(path);
|
|
return true;
|
|
} catch (err) {
|
|
try {
|
|
await this.createDirectory(path);
|
|
return true;
|
|
} catch (err) {
|
|
throw err;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
class WindowUtils extends Module {
|
|
bindings() {
|
|
this.openDevTools = this.openDevTools.bind(this);
|
|
this.executeJavascript = this.executeJavascript.bind(this);
|
|
this.injectScript = this.injectScript.bind(this);
|
|
}
|
|
|
|
get window() {
|
|
return this.state.window;
|
|
}
|
|
|
|
get webContents() {
|
|
return this.window.webContents;
|
|
}
|
|
|
|
openDevTools() {
|
|
this.webContents.openDevTools();
|
|
}
|
|
|
|
executeJavascript(script) {
|
|
this.webContents.executeJavaScript(script);
|
|
}
|
|
|
|
injectScript(fpath, variable) {
|
|
return WindowUtils.injectScript(this.window, fpath, variable);
|
|
}
|
|
|
|
static injectScript(window, fpath, variable) {
|
|
// console.log(`Injecting: ${fpath}`);
|
|
|
|
const escaped_path = fpath.replace(/\\/g, '\\\\').replace(/"/g, '\\"');
|
|
const escaped_variable = variable ? variable.replace(/\\/g, '\\\\').replace(/"/g, '\\"') : null;
|
|
|
|
if (variable) window.executeJavaScript(`window["${escaped_variable}"] = require("${escaped_path}");`);
|
|
else window.executeJavaScript(`require("${escaped_path}");`);
|
|
}
|
|
|
|
on(event, callback) {
|
|
this.webContents.on(event, callback);
|
|
}
|
|
|
|
send(channel, message) {
|
|
channel = channel.startsWith('bd-') ? channel : `bd-${channel}`;
|
|
this.webContents.send(channel, message);
|
|
}
|
|
}
|
|
|
|
module.exports = {
|
|
Utils,
|
|
FileUtils,
|
|
WindowUtils
|
|
};
|