First pass polyfill
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
const crypto = (() => {
|
||||
let cache = null;
|
||||
|
||||
return () => {
|
||||
if (cache) return cache;
|
||||
|
||||
return cache = __non_webpack_require__("crypto");
|
||||
};
|
||||
})();
|
||||
|
||||
export function createHash(type) {
|
||||
const hash = crypto().createHash(type);
|
||||
|
||||
const ctx = {
|
||||
update(data) {
|
||||
hash.update(data);
|
||||
|
||||
return ctx;
|
||||
},
|
||||
digest(encoding) {return hash.digest(encoding);}
|
||||
};
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
export function randomBytes(length) {
|
||||
return crypto().randomBytes(length);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import {ipcRenderer as IPC, shell} from "electron";
|
||||
|
||||
export const ipcRenderer = {
|
||||
send: IPC.send.bind(IPC),
|
||||
sendToHost: IPC.sendToHost.bind(IPC),
|
||||
sendTo: IPC.sendTo.bind(IPC),
|
||||
sendSync: IPC.sendSync.bind(IPC),
|
||||
invoke: IPC.invoke.bind(IPC),
|
||||
on: IPC.on.bind(IPC),
|
||||
off: IPC.off.bind(IPC)
|
||||
};
|
||||
|
||||
export {shell};
|
||||
@@ -0,0 +1,73 @@
|
||||
import * as fs from "fs";
|
||||
import cloneObject from "common/clone";
|
||||
import Logger from "common/logger";
|
||||
|
||||
export function readFile(path, options = "utf8") {
|
||||
return fs.readFileSync(path, options);
|
||||
}
|
||||
|
||||
export function writeFile(path, content, options) {
|
||||
if (content instanceof Uint8Array) {
|
||||
content = Buffer.from(content);
|
||||
}
|
||||
|
||||
const doWriteFile = options?.originalFs ? __non_webpack_require__("original-fs").writeFileSync : fs.writeFileSync;
|
||||
|
||||
return doWriteFile(path, content, options);
|
||||
}
|
||||
|
||||
export function readDirectory(path, options) {
|
||||
return fs.readdirSync(path, options);
|
||||
}
|
||||
|
||||
export function createDirectory(path, options) {
|
||||
return fs.mkdirSync(path, options);
|
||||
}
|
||||
|
||||
export function deleteDirectory(path, options) {
|
||||
fs.rmdirSync(path, options);
|
||||
}
|
||||
|
||||
export function exists(path) {
|
||||
return fs.existsSync(path);
|
||||
}
|
||||
|
||||
export function getRealPath(path, options) {
|
||||
return fs.realpathSync(path, options);
|
||||
}
|
||||
|
||||
export function rename(oldPath, newPath) {
|
||||
return fs.renameSync(oldPath, newPath);
|
||||
}
|
||||
|
||||
export function createWriteStream(path, options) {
|
||||
return cloneObject(fs.createWriteStream(path, options));
|
||||
}
|
||||
|
||||
export function watch(path, options, callback) {
|
||||
const watcher = fs.watch(path, options, (event, filename) => {
|
||||
try {
|
||||
callback(event, filename);
|
||||
}
|
||||
catch (error) {
|
||||
Logger.stacktrace("filesystem", "Failed to watch path", error);
|
||||
}
|
||||
});
|
||||
|
||||
return {
|
||||
close: () => {
|
||||
watcher.close();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function getStats(path, options) {
|
||||
const stats = fs.statSync(path, options);
|
||||
|
||||
return {
|
||||
...stats,
|
||||
isFile: stats.isFile.bind(stats),
|
||||
isDirectory: stats.isDirectory.bind(stats),
|
||||
isSymbolicLink: stats.isSymbolicLink.bind(stats)
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
import Logger from "common/logger";
|
||||
|
||||
let request;
|
||||
|
||||
const req = function (url, options, callback) {
|
||||
if (!request) request = __non_webpack_require__("request");
|
||||
|
||||
return request(url, options, (error, res, body) => {
|
||||
try {
|
||||
Reflect.apply(callback, null, [error, res, body]);
|
||||
}
|
||||
catch (err) {
|
||||
Logger.stacktrace("https", "Failed request", err);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const get = function (url, options, callback) {
|
||||
if (!request) request = __non_webpack_require__("request");
|
||||
|
||||
return request.get(url, options, (error, res, body) => {
|
||||
try {
|
||||
Reflect.apply(callback, null, [error, res, body]);
|
||||
}
|
||||
catch (err) {
|
||||
Logger.stacktrace("https", "Failed get request", err);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const put = function (url, options, callback) {
|
||||
if (!request) request = __non_webpack_require__("request");
|
||||
|
||||
return request.put(url, options, (error, res, body) => {
|
||||
try {
|
||||
Reflect.apply(callback, null, [error, res, body]);
|
||||
}
|
||||
catch (err) {
|
||||
Logger.stacktrace("https", "Failed put request", err);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export const post = function (url, options, callback) {
|
||||
if (!request) request = __non_webpack_require__("request");
|
||||
|
||||
return request.post(url, options, (error, res, body) => {
|
||||
try {
|
||||
Reflect.apply(callback, null, [error, res, body]);
|
||||
}
|
||||
catch (err) {
|
||||
Logger.stacktrace("https", "Failed post request", err);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const del = function (url, options, callback) {
|
||||
if (!request) request = __non_webpack_require__("request");
|
||||
|
||||
return request.delete(url, options, (error, res, body) => {
|
||||
try {
|
||||
Reflect.apply(callback, null, [error, res, body]);
|
||||
}
|
||||
catch (err) {
|
||||
Logger.stacktrace("https", "Failed delete request", err);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const head = function (url, options, callback) {
|
||||
if (!request) request = __non_webpack_require__("request");
|
||||
|
||||
return request.head(url, options, (error, res, body) => {
|
||||
try {
|
||||
Reflect.apply(callback, null, [error, res, body]);
|
||||
}
|
||||
catch (err) {
|
||||
Logger.stacktrace("https", "Failed head request", err);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
export default req;
|
||||
|
||||
Object.assign(req, {
|
||||
get,
|
||||
put,
|
||||
post,
|
||||
head,
|
||||
delete: del // eslint-disable-line quote-props
|
||||
});
|
||||
@@ -0,0 +1,14 @@
|
||||
import path from "path";
|
||||
import Module from "module";
|
||||
|
||||
Module.globalPaths.push(path.resolve(process.env.DISCORD_APP_PATH, "..", "app.asar", "node_modules"));
|
||||
|
||||
export * as filesystem from "./filesystem";
|
||||
export * as https from "./https";
|
||||
export * as electron from "./electron";
|
||||
export * as crypto from "./crypto";
|
||||
|
||||
// We can expose that without any issues.
|
||||
export * as path from "path";
|
||||
export * as net from "net"; // TODO: evaluate need and create wrapper
|
||||
export * as os from "os";
|
||||
+12
-56
@@ -1,59 +1,15 @@
|
||||
const Module = require("module");
|
||||
const path = require("path");
|
||||
const electron = require("electron");
|
||||
const NodeEvents = require("events");
|
||||
import {contextBridge} from "electron";
|
||||
import newProcess from "./process";
|
||||
import * as BdApi from "./api";
|
||||
import init from "./init";
|
||||
|
||||
const cloneObject = function (target, newObject = {}, keys) {
|
||||
if (!Array.isArray(keys)) keys = Object.keys(Object.getOwnPropertyDescriptors(target));
|
||||
return keys.reduce((clone, key) => {
|
||||
if (typeof(target[key]) === "object" && !Array.isArray(target[key]) && target[key] !== null && !(target[key] instanceof NodeEvents)) clone[key] = cloneObject(target[key], {});
|
||||
else clone[key] = target[key];
|
||||
|
||||
return clone;
|
||||
}, newObject);
|
||||
};
|
||||
|
||||
/* global window:false */
|
||||
|
||||
// const context = electron.webFrame.top.context;
|
||||
Object.defineProperty(window, "webpackJsonp", {
|
||||
get: () => electron.webFrame.top.context.webpackJsonp
|
||||
let hasInitialized = false;
|
||||
contextBridge.exposeInMainWorld("BetterDiscord", BdApi);
|
||||
contextBridge.exposeInMainWorld("process", newProcess);
|
||||
contextBridge.exposeInMainWorld("BetterDiscordPreload", () => {
|
||||
if (hasInitialized) return null;
|
||||
hasInitialized = true;
|
||||
return BdApi;
|
||||
});
|
||||
|
||||
electron.webFrame.top.context.global = electron.webFrame.top.context;
|
||||
electron.webFrame.top.context.require = require;
|
||||
electron.webFrame.top.context.Buffer = Buffer;
|
||||
|
||||
|
||||
electron.webFrame.top.context.process = new class PatchedProcess extends NodeEvents {
|
||||
get __ORIGINAL_PROCESS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED__() {return process;}
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
Object.assign(this,
|
||||
cloneObject(process, {}, Object.keys(NodeEvents.prototype)),
|
||||
cloneObject(process, {})
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
// Load Discord's original preload
|
||||
const preload = process.env.DISCORD_PRELOAD;
|
||||
if (preload) {
|
||||
|
||||
// Restore original preload for future windows
|
||||
electron.ipcRenderer.send("bd-register-preload", preload);
|
||||
// Run original preload
|
||||
try {
|
||||
const originalKill = process.kill;
|
||||
process.kill = function() {};
|
||||
require(preload);
|
||||
process.kill = originalKill;
|
||||
}
|
||||
catch (e) {
|
||||
// TODO bail out
|
||||
}
|
||||
}
|
||||
|
||||
Module.globalPaths.push(path.resolve(process.env.DISCORD_APP_PATH, "..", "app.asar", "node_modules"));
|
||||
init();
|
||||
@@ -0,0 +1,22 @@
|
||||
import {ipcRenderer as IPC} from "electron";
|
||||
import * as IPCEvents from "common/constants/ipcevents";
|
||||
|
||||
export default function() {
|
||||
// Load Discord's original preload
|
||||
const preload = process.env.DISCORD_PRELOAD;
|
||||
if (preload) {
|
||||
|
||||
// Restore original preload for future windows
|
||||
IPC.send(IPCEvents.REGISTER_PRELOAD, preload);
|
||||
// Run original preload
|
||||
try {
|
||||
const originalKill = process.kill;
|
||||
process.kill = function() {};
|
||||
__non_webpack_require__(preload);
|
||||
process.kill = originalKill;
|
||||
}
|
||||
catch (e) {
|
||||
// TODO bail out
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
import cloneObject from "common/clone";
|
||||
|
||||
export default cloneObject(process, {});
|
||||
@@ -19,7 +19,9 @@ module.exports = (env, argv) => ({
|
||||
rimraf: `require("rimraf")`,
|
||||
yauzl: `require("yauzl")`,
|
||||
mkdirp: `require("mkdirp")`,
|
||||
module: `require("module")`
|
||||
module: `require("module")`,
|
||||
os: `require("os")`,
|
||||
net: `require("net")`
|
||||
},
|
||||
resolve: {
|
||||
extensions: [".js"],
|
||||
|
||||
Reference in New Issue
Block a user