-
@@ -32,7 +35,8 @@
import { Globals, Updater } from 'modules';
import { ClientLogger as Logger } from 'common';
import SettingsWrapper from './SettingsWrapper.vue';
- import { FormButton } from '../common';
+ import UpdaterToggle from './UpdaterToggle.vue';
+ import UpdaterStatus from './UpdaterStatus.vue';
export default {
data() {
@@ -44,26 +48,29 @@
},
components: {
SettingsWrapper,
- FormButton
+ UpdaterToggle,
+ UpdaterStatus
},
computed: {
updatesAvailable() {
return this.updater.updatesAvailable;
},
newVersion() {
- return this.updater.latestVersion;
+ return '2.0.0-beta.4';
},
error() {
return this.updater.error;
+ },
+ updates() {
+ return this.updater.updates;
+ },
+ bdUpdates() {
+ return this.updater.bdUpdates;
}
},
methods: {
- async install() {
- this.updating = true;
- try {
- await this.updater.update();
- } catch (err) {}
- this.updating = false;
+ update() {
+ this.updater.startUpdate();
}
}
}
diff --git a/client/src/ui/components/bd/index.js b/client/src/ui/components/bd/index.js
index 5744e2ad..29b20c86 100644
--- a/client/src/ui/components/bd/index.js
+++ b/client/src/ui/components/bd/index.js
@@ -4,5 +4,8 @@ export { default as CssEditorView } from './CssEditor.vue';
export { default as PluginsView } from './PluginsView.vue';
export { default as ThemesView } from './ThemesView.vue';
export { default as UpdaterView } from './UpdaterView.vue';
+export { default as UpdaterStatus } from './UpdaterStatus.vue';
+export { default as UpdaterToggle } from './UpdaterToggle.vue';
export { default as BdBadge } from './BdBadge.vue';
export { default as ConnectivityView } from './ConnectivityView.vue';
+export { default as SuperSecretView } from './SuperSecretView.vue';
diff --git a/client/webpack.base.config.js b/client/webpack.base.config.js
index 1e266fc9..acd514f9 100644
--- a/client/webpack.base.config.js
+++ b/client/webpack.base.config.js
@@ -28,7 +28,6 @@ module.exports = {
},
externals: {
electron: 'require("electron")',
- asar: 'require("asar")',
fs: 'require("fs")',
path: 'require("path")',
util: 'require("util")',
diff --git a/client/webpack.config.js b/client/webpack.config.js
index 06f40f34..878cb51f 100644
--- a/client/webpack.config.js
+++ b/client/webpack.config.js
@@ -13,7 +13,10 @@ const config = {
},
plugins: [
new webpack.NamedModulesPlugin()
- ]
+ ],
+ externals: {
+ asar: 'require("asar")'
+ }
};
module.exports = merge(baseconfig, config);
diff --git a/client/webpack.production.config.js b/client/webpack.production.config.js
index 57bc0555..620a1b53 100644
--- a/client/webpack.production.config.js
+++ b/client/webpack.production.config.js
@@ -15,7 +15,10 @@ const config = {
new webpack.DefinePlugin({
PRODUCTION: JSON.stringify(true)
})
- ]
+ ],
+ externals: {
+ sparkplug: 'require("./sparkplug")'
+ }
};
module.exports = merge(baseconfig, config);
diff --git a/common/modules/axi.js b/common/modules/axi.js
new file mode 100644
index 00000000..0d215063
--- /dev/null
+++ b/common/modules/axi.js
@@ -0,0 +1,51 @@
+/**
+ * BetterDiscord axios wrapper
+ * Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
+ * All rights reserved.
+ * 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.
+*/
+
+import axios from 'axios';
+
+export default class AxiosWrapper {
+
+ static get axios() { return axios; }
+
+ static get github() {
+ return this._github ? this._github : (
+ this._github = {
+ main: this.create('https://github.com'),
+ api: this.create('https://api.github.com')
+ }
+ );
+ }
+
+ static get zl() {
+ return this._zl ? this._zl : (this._zl = {
+ api: this.create('https://zl', 1000, this.zlHeaders),
+ cdn: this.create('https://zl', 1000, this.zlHeaders)
+ });
+ }
+
+ static create(baseUrl, timeout = 1000, headers = null) {
+ return axios.create({ baseURL: baseUrl, timeout, headers: headers ? headers : this.defaultHeaders });
+ }
+
+ static get defaultHeaders() {
+ return {
+ 'User-Agent': 'BetterDiscordApp User'
+ };
+ }
+
+ static get zlHeaders() {
+ return {
+ 'User-Agent': 'BetterDiscordApp User',
+ 'X-ZL-Apikey': '1a20cce89a2dbd163fc9570f3246c20891e62b2818ada55f82fa3d1d96fa7ef4',
+ 'X-ZL-User': 'anonymous'
+ }
+ }
+
+}
diff --git a/common/modules/common.js b/common/modules/common.js
index 3ae581aa..96fe4b72 100644
--- a/common/modules/common.js
+++ b/common/modules/common.js
@@ -3,3 +3,4 @@ export { default as Filters } from './filters';
export { default as Logger, ClientLogger } from './logger';
export { default as ClientIPC } from './bdipc';
export { default as AsyncEventEmitter } from './async-eventemitter';
+export { default as Axi } from './axi';
diff --git a/core/package.json b/core/package.json
index 74868db5..6bf2a7ac 100644
--- a/core/package.json
+++ b/core/package.json
@@ -2,7 +2,7 @@
"name": "bdcore",
"description": "BetterDiscord core package",
"author": "Jiiks",
- "version": "2.0.0-beta.3",
+ "version": "2.0.0-beta.4",
"homepage": "https://betterdiscord.net",
"license": "MIT",
"main": "dist/main.js",
diff --git a/core/src/csp.json b/core/src/csp.json
new file mode 100644
index 00000000..60cda831
--- /dev/null
+++ b/core/src/csp.json
@@ -0,0 +1,25 @@
+{
+ "img-src": [
+ "https://cdn.betterttv.net",
+ "https://cdn.frankerfacez.com",
+ "https://i.imgur.com"
+ ],
+ "style-src": [
+ "https://fonts.googleapis.com"
+ ],
+ "script-src": [
+ "'sha256-fSHKdpQGCHaIqWP3SpJOuUHrLp49jy4dWHzZ/RBJ/p4='",
+ "'sha256-VFJcfKY5B3EBkFDgQnv3CozPwBlZcxwssfLVWlPFfZU='",
+ "'sha256-VzDmLZ4PxPkOS/KY7ITzLQsSWhfCnvUrNculcj8UNgE='",
+ "'sha256-l6K+77Z1cmldR9gIvaVWlboF/zr5MXCQHcsEHfnr5TU='"
+ ],
+ "connect-src": [
+ "https://github.com",
+ "https://api.github.com",
+ "https://betterdiscord.net",
+ "https://api.betterdiscord.net",
+ "https://cdn.betterdiscord.net",
+ "https://api.supersecretbdapiandcdn.net",
+ "https://cdn.supersecretbdapiandcdn.net"
+ ]
+}
diff --git a/core/src/csp.txt b/core/src/csp.txt
new file mode 100644
index 00000000..cac197d7
--- /dev/null
+++ b/core/src/csp.txt
@@ -0,0 +1,3 @@
+React Devtools: sha256-fSHKdpQGCHaIqWP3SpJOuUHrLp49jy4dWHzZ/RBJ/p4=
+Vue Devtools: sha256-VFJcfKY5B3EBkFDgQnv3CozPwBlZcxwssfLVWlPFfZU=
+Vue Detector: sha256-l6K+77Z1cmldR9gIvaVWlboF/zr5MXCQHcsEHfnr5TU=
diff --git a/core/src/main.js b/core/src/main.js
index 58cbfa66..18cd626a 100644
--- a/core/src/main.js
+++ b/core/src/main.js
@@ -8,11 +8,24 @@
* LICENSE file in the root directory of this source tree.
*/
+/*PRODUCTION*/
const TESTS = typeof PRODUCTION === 'undefined';
const TEST_ARGS = () => {
const _basePath = path.resolve(__dirname, '..', '..');
- const _baseDataPath = path.resolve(_basePath, 'tests');
+ const _baseDataPath = path.resolve(_basePath, 'tests');
+
+ const _corePkg = require(path.resolve(_basePath, 'core', 'package.json'));
+ const _clientPkg = require(path.resolve(_basePath, 'client', 'package.json'));
+ const _editorPkg = require(path.resolve(_basePath, 'editor', 'package.json'));
+
+ const coreVersion = _corePkg.version;
+ const clientVersion = _clientPkg.version;
+ const editorVersion = _editorPkg.version;
+
return {
+ coreVersion,
+ clientVersion,
+ editorVersion,
'options': {
'autoInject': true,
'commonCore': true,
@@ -26,7 +39,7 @@ const TEST_ARGS = () => {
}
}
}
-const TEST_EDITOR = true;
+const TEST_EDITOR = TESTS && true;
import path from 'path';
import sass from 'node-sass';
@@ -35,21 +48,14 @@ import deepmerge from 'deepmerge';
import ContentSecurityPolicy from 'csp-parse';
import keytar from 'keytar';
-import { FileUtils, BDIpc, Config, WindowUtils, CSSEditor, Editor, Database } from './modules';
+import { FileUtils, BDIpc, Config, WindowUtils, Updater, Editor, Database } from './modules';
const packageJson = require(path.resolve(__dirname, 'package.json'));
const sparkplug = path.resolve(__dirname, 'sparkplug.js');
let configProxy;
-const CSP = {
- 'img-src': ['https://cdn.betterttv.net', 'https://cdn.frankerfacez.com'],
- 'script-src': [
- `'sha256-fSHKdpQGCHaIqWP3SpJOuUHrLp49jy4dWHzZ/RBJ/p4='`, // React Devtools
- `'sha256-VFJcfKY5B3EBkFDgQnv3CozPwBlZcxwssfLVWlPFfZU='`, // Vue Devtools
- `'sha256-VzDmLZ4PxPkOS/KY7ITzLQsSWhfCnvUrNculcj8UNgE=' 'sha256-l6K+77Z1cmldR9gIvaVWlboF/zr5MXCQHcsEHfnr5TU='` // Vue Detector
- ]
-};
+const CSP = TESTS ? require('../src/csp.json') : require('./csp.json');
class Comms {
constructor(bd) {
@@ -195,6 +201,8 @@ export class BetterDiscord {
get config() { return this._config ? this._config : (this._config = new Config(this._args)); }
get window() { return this.windowUtils ? this.windowUtils.window : undefined; }
get editor() { return this._editor ? this._editor : (this._editor = new Editor(this, this.config.getPath('editor'))); }
+ get updater() { return this._updater ? this._updater : (this._updater = new Updater(this)); }
+ get sendToDiscord() { return this.windowUtils.send; }
constructor(args) {
if (TESTS) args = TEST_ARGS();
@@ -209,13 +217,16 @@ export class BetterDiscord {
this.config.compatibility();
this.bindings();
- this.parseClientPackage();
this.extraPaths();
+ this.parseClientPackage();
+ this.parseEditorPackage();
+ this.parseCorePackage();
this.database.init();
configProxy = () => this.config;
const autoInitComms = this.comms;
const autoInitEditor = this.editor;
+ this.updater.start();
this.init();
}
@@ -280,7 +291,7 @@ export class BetterDiscord {
*/
parseClientPackage() {
const clientPath = this.config.getPath('client');
- const clientPkg = TESTS ? require(`${path.resolve(clientPath, '..')}/package.json`) :require(`${clientPath}/package.json`);
+ const clientPkg = TESTS ? require(`${path.resolve(clientPath, '..')}/package.json`) : require(`${clientPath}/package.json`);
const { version } = clientPkg;
const main = TESTS ? 'betterdiscord.client.js' : clientPkg.main;
this.config.addPath('client_script', `${clientPath}/${main}`);
@@ -288,6 +299,20 @@ export class BetterDiscord {
console.log(`[BetterDiscord] Client v${this.config.clientVersion} - ${this.config.getPath('client_script')}`);
}
+ parseCorePackage() {
+ const corePath = this.config.getPath('core');
+ const corePkg = TESTS ? require(`${path.resolve(corePath, '..')}/package.json`) : require(`${corePath}/package.json`);
+ const { version } = corePkg;
+ this.config.setCoreVersion(version);
+ }
+
+ parseEditorPackage() {
+ const editorPath = this.config.getPath('editor');
+ const editorPkg = TESTS ? require(`${path.resolve(editorPath, '..')}/package.json`) : require(`${editorPath}/package.json`);
+ const { version } = editorPkg;
+ this.config.setEditorVersion(version);
+ }
+
/**
* Add extra paths to config
*/
diff --git a/core/src/modules/axi.js b/core/src/modules/axi.js
new file mode 100644
index 00000000..84023088
--- /dev/null
+++ b/core/src/modules/axi.js
@@ -0,0 +1,53 @@
+/**
+ * BetterDiscord axios wrapper
+ * Copyright (c) 2015-present Jiiks/JsSucks - https://github.com/Jiiks / https://github.com/JsSucks
+ * All rights reserved.
+ * 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.
+*/
+
+import axios from 'axios';
+
+export default class AxiosWrapper {
+
+ static get axios() { return axios; }
+
+ static get(url) { return axios.get(url) }
+
+ static get github() {
+ return this._github ? this._github : (
+ this._github = {
+ main: this.create('https://github.com'),
+ api: this.create('https://api.github.com')
+ }
+ );
+ }
+
+ static get zl() {
+ return this._zl ? this._zl : (this._zl = {
+ api: this.create('https://zl', 1000, this.zlHeaders),
+ cdn: this.create('https://zl', 1000, this.zlHeaders)
+ });
+ }
+
+ static create(baseUrl, timeout = 1000, headers = null) {
+ return axios.create({ baseURL: baseUrl, timeout, headers: headers ? headers : this.defaultHeaders });
+ }
+
+ static get defaultHeaders() {
+ return {
+ 'User-Agent': 'BetterDiscordApp User'
+ };
+ }
+
+ static get zlHeaders() {
+ return {
+ 'User-Agent': 'BetterDiscordApp User',
+ 'X-ZL-Apikey': '1a20cce89a2dbd163fc9570f3246c20891e62b2818ada55f82fa3d1d96fa7ef4',
+ 'X-ZL-User': 'anonymous'
+ }
+ }
+
+}
diff --git a/core/src/modules/config.js b/core/src/modules/config.js
index c81ba5de..43559729 100644
--- a/core/src/modules/config.js
+++ b/core/src/modules/config.js
@@ -16,12 +16,36 @@ export default class Config extends Module {
return this.args.version;
}
+ get versions() {
+ return {
+ core: this.coreVersion,
+ client: this.clientVersion,
+ editor: this.editorVersion
+ };
+ }
+
+ get coreVersion() {
+ return this.state.coreVersion;
+ }
+
get clientVersion() {
- return this.args.clientVersion;
+ return this.state.clientVersion;
+ }
+
+ get editorVersion() {
+ return this.state.editorVersion;
}
setClientVersion(clientVersion) {
- this.args.clientVersion = clientVersion;
+ this.state.clientVersion = clientVersion;
+ }
+
+ setCoreVersion(coreVersion) {
+ this.state.coreVersion = coreVersion;
+ }
+
+ setEditorVersion(editorVersion) {
+ this.state.editorVersion = editorVersion;
}
get paths() {
@@ -41,6 +65,7 @@ export default class Config extends Module {
get config() {
return {
version: this.version,
+ versions: this.versions,
paths: this.paths
};
}
diff --git a/core/src/modules/index.js b/core/src/modules/index.js
index 4a56e948..2b98833e 100644
--- a/core/src/modules/index.js
+++ b/core/src/modules/index.js
@@ -4,3 +4,4 @@ export { default as Config } from './config';
export { default as CSSEditor } from './csseditor';
export { default as Editor } from './editor';
export { default as Database } from './database';
+export { default as Updater } from './updater';
diff --git a/core/src/modules/modulebase.js b/core/src/modules/modulebase.js
index 5623e3e9..6a630548 100644
--- a/core/src/modules/modulebase.js
+++ b/core/src/modules/modulebase.js
@@ -11,6 +11,9 @@
/**
* Base Module that every non-static module should extend.
*/
+
+import { default as BDIpc } from './bdipc';
+
export default class Module {
constructor(args) {
@@ -24,6 +27,7 @@ export default class Module {
init() {
if (this.bindings) this.bindings();
if (this.setInitialState) this.setInitialState(this.state);
+ if (this.events) this.events(BDIpc);
}
set args(t) {}
diff --git a/core/src/modules/updater.js b/core/src/modules/updater.js
new file mode 100644
index 00000000..4c82f032
--- /dev/null
+++ b/core/src/modules/updater.js
@@ -0,0 +1,287 @@
+/**
+ * BetterDiscord Updater 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.
+*/
+
+
+import Module from './modulebase';
+import { FileUtils } from './utils';
+import semver from 'semver';
+import Axi from './axi';
+import zlib from 'zlib';
+import tarfs from 'tar-fs';
+
+const TEST_UPDATE = [
+ {
+ 'id': 'core',
+ 'version': '2.0.0-beta.5'
+ },
+ {
+ 'id': 'client',
+ 'version': '2.0.0-beta.5'
+ },
+ {
+ 'id': 'editor',
+ 'version': '0.4.1'
+ }
+];
+
+class ReleaseInfo {
+
+ constructor(versions) {
+ this.versions = versions;
+ }
+
+ get core() {
+ const f = this.files.find(f => f.id === 'core');
+ f.upToDate = semver.satisfies(this.versions.core, `>=${f.version}`, { includePrerelease: true });
+ f.currentVersion = this.versions.core;
+ return f;
+ }
+
+ get client() {
+ const f = this.files.find(f => f.id === 'client');
+ f.upToDate = semver.satisfies(this.versions.client, `>=${f.version}`, { includePrerelease: true });
+ f.currentVersion = this.versions.client;
+ return f;
+ }
+
+ get editor() {
+ const f = this.files.find(f => f.id === 'editor');
+ f.upToDate = semver.satisfies(this.versions.editor, `>=${f.version}`, { includePrerelease: true });
+ f.currentVersion = this.versions.editor;
+ return f;
+ }
+
+ test() {
+ this.files = TEST_UPDATE;
+ }
+
+}
+
+export default class Updater extends Module {
+
+ constructor(bd) {
+ super();
+ this.bd = bd;
+ }
+
+ bindings() {
+ this.checkForUpdates = this.checkForUpdates.bind(this);
+ this.checkForBdUpdates = this.checkForBdUpdates.bind(this);
+ this.updateAll = this.updateAll.bind(this);
+ this.updateFinished = this.updateFinished.bind(this);
+ this.start = this.start.bind(this);
+ }
+
+ events(ipc) {
+ ipc.on('updater-startUpdate', (_, updates) => {
+ clearInterval(this.updaterThread);
+ this.updateAll(updates);
+ });
+ ipc.on('debug-updater-forceUpdate', () => {
+ this.checkForUpdates(true);
+ });
+ }
+
+ async updateBd(update) {
+ try {
+ console.log('[BetterDiscord:Updater] Updating', update.id);
+ await this.downloadTarGz(`https://github.com/JsSucks/BetterDiscordApp${update.remote}`, this.bd.config.getPath('base'));
+ this.updateFinished(update);
+ // Cleanup
+ await FileUtils.rm(`${this.bd.config.getPath(update.id)}_old`);
+ } catch (err) {
+ console.log('[BetterDiscord:Updater] Failed to update', update.id);
+ console.log(err);
+ update.error = err;
+ this.bd.sendToDiscord('updater-updateError', update);
+ }
+ }
+
+ async updateAll(updates) {
+ const bd = updates.bd || [];
+ const plugins = updates.plugins || [];
+ const themes = updates.themes || [];
+ const modules = updates.modules || [];
+
+ this.restartRequired = this.reloadRequired = false;
+ this.finishedUpdates = 0;
+ this.totalUpdates = bd.length + plugins.length + themes.length + modules.length;
+
+ const renamed = [];
+ // TODO cleaner
+ if (bd.length) {
+ for (const update of bd) {
+ try {
+ await FileUtils.rm(`${this.bd.config.getPath(update.id)}_old`);
+ // Try to rename dirs first
+ await FileUtils.rn(this.bd.config.getPath(update.id), `${this.bd.config.getPath(update.id)}_old`);
+ renamed.push({ 'old': this.bd.config.getPath(update.id), 'new': `${this.bd.config.getPath(update.id)}_old`});
+ } catch (err) {
+ if (renamed.length) {
+ // Restore dirs
+ for (const r of renamed) {
+ await FileUtils.rn(r.new, r.old);
+ }
+ }
+
+ throw err;
+ }
+ }
+
+ for (const update of bd) {
+ this.updateBd(update);
+ }
+ }
+
+ }
+
+ updateFinished(update) {
+ if (update.id === 'core') this.restartRequired = true;
+ if (update.id === 'client') this.reloadRequired = true;
+
+ console.log('[BetterDiscord:Updater] Finished updating', update.id);
+ this.bd.sendToDiscord('updater-updateFinished', update);
+
+ this.finishedUpdates++;
+ if (this.finishedUpdates >= this.totalUpdates) {
+ this.bd.sendToDiscord('updater-updated', { restartRequired: this.restartRequired, reloadRequired: this.reloadRequired });
+ }
+ }
+
+ start(interval = 30) {
+ this.updaterThread = setInterval(this.checkForUpdates, interval * 60 * 1000);
+ }
+
+ validate(releaseInfo) {
+ return releaseInfo &&
+ typeof releaseInfo === 'object' &&
+ releaseInfo.files &&
+ Array.isArray(releaseInfo.files) &&
+ releaseInfo.files.length >= 4;
+ }
+
+ async latestRelease() {
+ try {
+ const release = await Axi.github.api.get('repos/JsSucks/BetterDiscordApp/releases/latest'); // TODO replace with config
+ const releaseInfoAsset = release.data.assets.find(asset => asset.name === 'releaseinfo.json');
+ const releaseInfo = await Axi.get(releaseInfoAsset['browser_download_url']);
+
+ if (this.validate(releaseInfo.data)) return releaseInfo.data;
+ return this.latestReleaseFallback();
+ } catch (err) {
+ console.log(err);
+ return this.latestReleaseFallback();
+ }
+ }
+
+ async latestReleaseFallback() {
+ console.log('fallback');
+ }
+
+ async checkForBdUpdates(forced = false) {
+ try {
+ const { coreVersion, clientVersion, editorVersion } = this.bd.config;
+ const releaseInfo = new ReleaseInfo({ core: coreVersion, client: clientVersion, editor: editorVersion });
+
+ const latestRelease = await this.latestRelease();
+
+ if (forced) {
+ latestRelease.files = latestRelease.files.map(file => {
+ file.version = '10.0.0';
+ return file;
+ });
+ }
+
+ releaseInfo.files = latestRelease.files;
+
+ const updates = [];
+
+ const { core, client, editor } = releaseInfo;
+ if (!core.upToDate) updates.push(core);
+ if (!client.upToDate) updates.push(client);
+ if (!editor.upToDate) updates.push(editor);
+
+ return updates;
+
+ } catch (err) {
+ console.log('[BetterDiscord:Updater]', err);
+ return [];
+ }
+ }
+
+ async checkForUpdates(forced = false) {
+ console.log('[BetterDiscord:Updater] Checking for updates');
+ this.bd.sendToDiscord('updater-checkForUpdates', '');
+
+ try {
+ const bd = await this.checkForBdUpdates(forced);
+ const updates = { bd, haveUpdates: false };
+
+ if (bd.length) updates.haveUpdates = true;
+
+ if (!updates.haveUpdates) {
+ this.bd.sendToDiscord('updater-noUpdates', '');
+ return true;
+ }
+
+ this.bd.sendToDiscord('updater-updatesAvailable', updates);
+
+ return true;
+
+ } catch (err) {
+ console.log('[BetterDiscord:Updater]', err);
+ this.bd.sendToDiscord('updater-error', err);
+ return 'err';
+ }
+ }
+
+ async downloadTarGz(url, dest, responseType = 'stream', headers = null) {
+ try {
+ const stream = await Axi.axios({
+ url,
+ type: 'GET',
+ responseType,
+ headers: headers ||
+ {
+ 'Content-Type': 'application/octet-stream',
+ 'Accept': 'application/octet-stream'
+ }
+ });
+
+ return new Promise((resolve, reject) => {
+ stream.data.pipe(zlib.createGunzip()).pipe(tarfs.extract(dest)).on('finish', resolve).on('error', reject);
+ });
+ } catch (err) {
+ throw err;
+ }
+ }
+
+ debug(releaseInfo) {
+ const { core, client, editor } = releaseInfo;
+ if (!core.upToDate) {
+ console.log(`[BetterDiscord:Updater] Core update available: ${core.currentVersion} > ${core.version}`);
+ } else {
+ console.log(`[BetterDiscord:Updater] Core up to date: ${core.currentVersion} = ${core.version}`);
+ }
+
+ if (!client.upToDate) {
+ console.log(`[BetterDiscord:Updater] Client update available: ${client.currentVersion} > ${client.version}`);
+ } else {
+ console.log(`[BetterDiscord:Updater] Client up to date: ${client.currentVersion} = ${client.version}`);
+ }
+
+ if (!editor.upToDate) {
+ console.log(`[BetterDiscord:Updater] Editor update available: ${editor.currentVersion} > ${editor.version}`);
+ } else {
+ console.log(`[BetterDiscord:Updater] Editor up to date: ${editor.currentVersion} = ${editor.version}`);
+ }
+ }
+
+}
diff --git a/csseditor/package.json b/csseditor/package.json
deleted file mode 100644
index 1692bb58..00000000
--- a/csseditor/package.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
- "name": "bdcsseditor",
- "description": "BetterDiscord css editor package",
- "author": "Jiiks",
- "version": "0.4.0",
- "homepage": "https://betterdiscord.net",
- "license": "MIT",
- "main": "dist/csseditor.js",
- "contributors": [
- "Jiiks",
- "Pohky"
- ],
- "repository": {
- "type": "git",
- "url": "https://github.com/JsSucks/BetterDiscordApp.git"
- },
- "private": false,
- "scripts": {
- "build": "webpack --progress --colors",
- "watch": "webpack --progress --colors --watch",
- "release": "webpack --progress --colors --config=webpack.production.config.js"
- }
-}
diff --git a/csseditor/src/Editor.vue b/csseditor/src/Editor.vue
deleted file mode 100644
index e6b8324c..00000000
--- a/csseditor/src/Editor.vue
+++ /dev/null
@@ -1,191 +0,0 @@
-
-
-
-
-
-
CSS Editor
-
-
- P
- X
-
-
-
-
Loading Please Wait...
-
-
-
-
-
{{ error.formatted }}
-
-
-
-
-
diff --git a/csseditor/src/index.js b/csseditor/src/index.js
deleted file mode 100644
index 9146bd05..00000000
--- a/csseditor/src/index.js
+++ /dev/null
@@ -1,27 +0,0 @@
-// const styles = require('./styles/index.scss');
-
-import Vue from 'vue';
-import VueCodemirror from 'vue-codemirror';
-
-import Editor from './Editor.vue';
-import styles from './styles/index.scss';
-
-Vue.use(VueCodemirror, {});
-
-window.cmCommands = VueCodemirror.CodeMirror.commands;
-
-const mount = document.createElement('div');
-mount.classList.add('container');
-document.body.appendChild(mount);
-
-const vue = new Vue({
- el: mount,
- components: { Editor },
- template: '
'
-});
-
-const style = document.createElement('style');
-style.id = 'bd-main';
-style.type = 'text/css';
-style.appendChild(document.createTextNode(styles));
-document.head.appendChild(style);
diff --git a/csseditor/src/styles/codemirror.scss b/csseditor/src/styles/codemirror.scss
deleted file mode 100644
index b945ac14..00000000
--- a/csseditor/src/styles/codemirror.scss
+++ /dev/null
@@ -1,105 +0,0 @@
-.CodeMirror-scroll {
- cursor: text;
-}
-
-.CodeMirror-overlayscroll .CodeMirror-scrollbar-filler {
- background: #38444a;
-}
-
-.CodeMirror-overlayscroll-horizontal div,
-.CodeMirror-overlayscroll-vertical div {
- background: rgb(41, 43, 47);
-}
-
-.CodeMirror-overlayscroll-horizontal,
-.CodeMirror-overlayscroll-horizontal div {
- height: 10px;
-}
-
-.CodeMirror-overlayscroll-vertical,
-.CodeMirror-overlayscroll-vertical div {
- width: 10px;
-}
-
-.CodeMirror-scrollbar-filler {
- width: 10px;
- height: 10px;
- background: rgb(41, 43, 47);
-}
-
-.cm-s-material.CodeMirror {
- background: #36393f;
-}
-
-.CodeMirror-scroll {
- cursor: text;
-}
-
-.cm-s-material .CodeMirror-gutters {
- background: #292b2f;
-}
-
-.CodeMirror-gutter {
- min-width: 34px;
- border-right: 1px solid hsla(218,5%,47%,.3);
- cursor: default;
-}
-
-.CodeMirror-hints {
- /*background: #1e262a;*/
- background: #292b2f;
- box-shadow: 2px 3px 5px rgba(4, 4, 4, 0.22);
- border: 1px solid #262f33;
-
- &::-webkit-scrollbar {
- background: transparent;
- }
-
- &::-webkit-scrollbar-thumb {
- background-color: rgba(0,0,0,.4);
- border-color: transparent;
- }
-
- &::-webkit-scrollbar-thumb,
- &::-webkit-scrollbar-track {
- background-clip: padding-box;
- border-width: 3px;
- border-style: solid;
- border-radius: 7px;
- }
-
- &::-webkit-scrollbar-track {
- background-color: transparent;
- border-color: transparent;
- }
-}
-
-.CodeMirror-linenumber,
-.CodeMirror-line {
- padding: 0 5px !important;
-}
-
-.CodeMirror-linenumber {
- cursor: text;
-}
-
-.cm-s-material .CodeMirror-linenumber {
- color: #f6f6f7;
-}
-
-.CodeMirror-hint {
- color: #bac9d2;
-}
-
-li.CodeMirror-hint-active {
- color: #bac9d2;
- /*background: #3b4950;*/
- background: #36393f;
-}
-
-.CodeMirror-dialog-top {
- bottom: 0;
- top: auto;
- border: none;
- background: #1e262a;
-}
diff --git a/csseditor/src/styles/editor.scss b/csseditor/src/styles/editor.scss
deleted file mode 100644
index a46844dc..00000000
--- a/csseditor/src/styles/editor.scss
+++ /dev/null
@@ -1,17 +0,0 @@
-.editor {
- display: flex;
- flex-direction: column;
- flex-grow: 1;
- overflow: hidden;
-
- .vue-codemirror {
- display: flex;
- flex-direction: column;
- flex-grow: 1;
- overflow: hidden;
-
- &, & .CodeMirror {
- flex-grow: 1;
- }
- }
-}
diff --git a/csseditor/src/styles/images.scss b/csseditor/src/styles/images.scss
deleted file mode 100644
index 202ab708..00000000
--- a/csseditor/src/styles/images.scss
+++ /dev/null
@@ -1,2 +0,0 @@
-$logoSmallGw: url(data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkltYWdlIiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHhtbG5zOnhsaW5rPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hsaW5rIiB4PSIwcHgiIHk9IjBweCIgdmlld0JveD0iMCAwIDUxMiA1MTIiIHN0eWxlPSJlbmFibGUtYmFja2dyb3VuZDpuZXcgMCAwIDUxMiA1MTI7IiB4bWw6c3BhY2U9InByZXNlcnZlIj48c3R5bGUgdHlwZT0idGV4dC9jc3MiPi5zdDB7ZGlzcGxheTpub25lO30uc3Qxe2Rpc3BsYXk6aW5saW5lO2ZpbGw6IzAyMDAzNTtzdHJva2U6IzAwMDAwMDtzdHJva2UtbWl0ZXJsaW1pdDoxMDt9LnN0MntmaWxsOiMzRUNDOUU7fS5zdDN7ZmlsbDojRkZGRkZGO308L3N0eWxlPjxnIGlkPSJMYXllcl8yIiBjbGFzcz0ic3QwIj48cmVjdCB4PSItNjQiIHk9Ii0zMiIgY2xhc3M9InN0MSIgd2lkdGg9IjYxOCIgaGVpZ2h0PSI1NzIiLz48L2c+PGcgaWQ9IkxheWVyXzEiIHhtbG5zOnZlY3Rvcm5hdG9yPSJodHRwOi8vdmVjdG9ybmF0b3IuaW8iPjxwYXRoIGNsYXNzPSJzdDIiIGQ9Ik03MCwxOC44Yy0xMy43LDAtMjcuMywxMy43LTI3LjMsMjcuM3YyMzMuNkM0Mi43LDM5Ny43LDEzNy45LDQ5MywyNTYsNDkzYzI5LjcsMCw1OC02LjEsODMuNi0xN1YzNDEuNWMtMTksMjUuNi00OS4zLDQyLjItODMuNiw0Mi4yYy01Ny42LDAtMTA0LjEtNDYuNS0xMDQuMS0xMDQuMVY0Ni4xYzAtMTMuNy0xMy43LTI3LjMtMjcuMy0yNy4zSDcweiIvPjxwYXRoIGNsYXNzPSJzdDMiIGQ9Ik0zODcuNCwxOC44Yy0xMy43LDAtMjcuMywxMy43LTI3LjMsMjcuM3Y0Ny4zQzMyOS4zLDc2LjIsMjkzLjksNjYuMywyNTYsNjYuM2MtMjkuOCwwLTU3LjksNi4zLTgzLjYsMTcuM3YxMzQuMmMxOS0yNS42LDQ5LjMtNDIuMiw4My42LTQyLjJjNTcuNiwwLDEwNC4xLDQ2LjUsMTA0LjEsMTA0LjF2MTg2LjJjNjUuMi0zNi40LDEwOS4yLTEwNiwxMDkuMi0xODYuMlY0Ni4xYzAtMTguOC0xMy43LTI3LjMtMjcuMy0yNy4zSDM4Ny40eiIvPjwvZz48L3N2Zz4=);
-$bdicon: $logoSmallGw;
diff --git a/csseditor/src/styles/index.scss b/csseditor/src/styles/index.scss
deleted file mode 100644
index a3ed0e36..00000000
--- a/csseditor/src/styles/index.scss
+++ /dev/null
@@ -1,13 +0,0 @@
-@import '../../../node_modules/codemirror/lib/codemirror.css';
-@import '../../../node_modules/codemirror/theme/material.css';
-@import '../../../node_modules/codemirror/addon/scroll/simplescrollbars.css';
-@import '../../../node_modules/codemirror/addon/dialog/dialog.css';
-@import '../../../node_modules/codemirror/addon/hint/show-hint.css';
-
-@import './images.scss';
-@import './main.scss';
-@import './titlebar.scss';
-@import './spinner.scss';
-@import './editor.scss';
-@import './tools.scss';
-@import './codemirror.scss';
diff --git a/csseditor/src/styles/main.scss b/csseditor/src/styles/main.scss
deleted file mode 100644
index 20c89ea8..00000000
--- a/csseditor/src/styles/main.scss
+++ /dev/null
@@ -1,36 +0,0 @@
-html, body {
- margin: 0;
- padding: 0;
- max-height: 100%;
- height: 100%;
- background: #2c383e;
- min-width: 700px;
- min-height: 400px;
-}
-
-* {
- outline: none;
-}
-
-.flex-spacer {
- flex-grow: 1;
-}
-
-.flex-row {
- display: flex;
- flex-direction: row;
-}
-
-.valign {
- position: absolute;
- left: 50%;
- top: 50%;
- transform: translate(-50%, -50%);
-}
-
-.container {
- display: flex;
- flex-grow: 1;
- flex-direction: column;
- height: 100%;
-}
diff --git a/csseditor/src/styles/spinner.scss b/csseditor/src/styles/spinner.scss
deleted file mode 100644
index 97acdd91..00000000
--- a/csseditor/src/styles/spinner.scss
+++ /dev/null
@@ -1,14 +0,0 @@
-#spinner {
- background: rgba(51, 48, 48, 0.41);
- position: absolute;
- top: 34px;
- left: 0;
- right: 0;
- bottom: 0;
- color: #bac9d2;
- font-family: Whitney,Helvetica Neue,Helvetica,Arial,sans-serif;
- font-weight: 600;
- font-size: 2em;
- z-index: 90000;
- user-select: none;
-}
diff --git a/csseditor/src/styles/titlebar.scss b/csseditor/src/styles/titlebar.scss
deleted file mode 100644
index b837087a..00000000
--- a/csseditor/src/styles/titlebar.scss
+++ /dev/null
@@ -1,71 +0,0 @@
-.titlebar {
- display: flex;
- height: 25px;
- padding: 4px 5px;
- background: #292b2f;
- border-bottom: 1px solid hsla(218,5%,47%,.3);
- user-select: none;
- cursor: default;
-
- .icon {
- width: 31px;
- height: 25px;
-
- .inner {
- width: 25px;
- height: 25px;
- background-image: $bdicon;
- background-size: 22px 22px;
- background-repeat: no-repeat;
- background-position: center;
- }
- }
-
- .title {
- color: #bac9d2;
- font-family: Whitney,Helvetica Neue,Helvetica,Arial,sans-serif;
- line-height: 25px;
- font-size: 15px;
- }
-
- .controls {
- margin: 0 0 0 2px;
- font-size: 0;
-
- button {
- -webkit-app-region: no-drag;
- border-radius: 3px;
- width: 25px;
- font-size: 12px;
- font-weight: 600;
- background: #36393f;
- color: #bac9d2;
- font-family: Whitney,Helvetica Neue,Helvetica,Arial,sans-serif;
- transition: background-color .2s ease, color .2s ease;
- cursor: default;
- border: 0;
- height: 25px;
- z-index: 900062;
- padding: 0;
- margin: 0 0 0 4px;
-
- &:hover {
- background: #44474e;
- color: #FFF;
- }
-
- &.active {
- background: #3a71c1;
- }
- }
- }
-
- .draggable {
- top: 0;
- left: 0;
- right: 63px;
- position: absolute;
- height: 33px;
- -webkit-app-region: drag;
- }
-}
diff --git a/csseditor/src/styles/tools.scss b/csseditor/src/styles/tools.scss
deleted file mode 100644
index 2a4ae589..00000000
--- a/csseditor/src/styles/tools.scss
+++ /dev/null
@@ -1,66 +0,0 @@
-.parser-error {
- padding: 4px 6px;
- background: #292b2f;
- border-top: 1px solid hsla(218,5%,47%,.3);
- color: #d84040;
- font-family: monospace;
- white-space: pre-wrap;
- font-size: 12px;
-}
-
-.tools {
- height: 36px;
- background: #292b2f;
- border-top: 1px solid hsla(218,5%,47%,.3);
- display: flex;
- flex-direction: column;
- user-select: none;
-
- .flex-row {
- flex-grow: 1;
- padding: 4px 5px;
- }
-
- button {
- border-radius: 3px;
- width: 100px;
- padding: 3px 10px;
- font-size: 12px;
- font-weight: 600;
- background: #36393f;
- color: #bac9d2;
- font-family: Whitney,Helvetica Neue,Helvetica,Arial,sans-serif;
- transition: background-color .2s ease, color .2s ease;
- cursor: pointer;
- border: 0;
- margin-right: 4px;
- flex: 0 0 auto;
-
- &:hover {
- background: #44474e;
- color: #fff;
- }
- }
-
- #chkboxLiveUpdate {
- padding: 3px 10px;
- line-height: 22px;
- flex: 0 0 auto;
-
- label {
- cursor: pointer;
- }
-
- input[type="checkbox"] {
- margin: 0 6px 0 0;
- cursor: pointer;
- }
-
- span {
- font-size: 12px;
- font-weight: 500;
- color: #bac9d2;
- font-family: Whitney,Helvetica Neue,Helvetica,Arial,sans-serif;
- }
- }
-}
diff --git a/csseditor/webpack.config.js b/csseditor/webpack.config.js
deleted file mode 100644
index 67f86166..00000000
--- a/csseditor/webpack.config.js
+++ /dev/null
@@ -1,43 +0,0 @@
-const path = require('path');
-const VueLoaderPlugin = require('vue-loader/lib/plugin');
-
-const vueLoader = {
- test: /\.(vue)$/,
- exclude: /node_modules/,
- use: 'vue-loader'
-};
-
-const scssLoader = {
- test: /\.(css|scss)$/,
- use: ['css-loader', 'sass-loader']
-};
-
-module.exports = {
- entry: './src/index.js',
- mode: 'development',
- output: {
- path: path.resolve(__dirname, 'dist'),
- filename: 'csseditor.js'
- },
- module: {
- rules: [vueLoader, scssLoader]
- },
- externals: {
- electron: 'window.require("electron")',
- fs: 'window.require("fs")',
- util: 'window.require("util")',
- process: 'require("process")'
- },
- resolve: {
- alias: {
- vue$: path.resolve('..', 'node_modules', 'vue', 'dist', 'vue.esm.js')
- },
- modules: [
- path.resolve('..', 'node_modules'),
- path.resolve('..', 'common', 'modules')
- ]
- },
- plugins: [
- new VueLoaderPlugin()
- ]
-};
diff --git a/csseditor/webpack.production.config.js b/csseditor/webpack.production.config.js
deleted file mode 100644
index 780c7111..00000000
--- a/csseditor/webpack.production.config.js
+++ /dev/null
@@ -1,47 +0,0 @@
-const path = require('path');
-const webpack = require('webpack');
-const VueLoaderPlugin = require('vue-loader/lib/plugin');
-
-const vueLoader = {
- test: /\.(vue)$/,
- exclude: /node_modules/,
- use: 'vue-loader'
-};
-
-const scssLoader = {
- test: /\.(css|scss)$/,
- use: ['css-loader', 'sass-loader']
-};
-
-module.exports = {
- entry: './src/index.js',
- mode: 'production',
- output: {
- path: path.resolve(__dirname, 'dist'),
- filename: 'csseditor-release.js'
- },
- module: {
- rules: [vueLoader, scssLoader]
- },
- externals: {
- electron: 'window.require("electron")',
- fs: 'window.require("fs")',
- util: 'window.require("util")',
- process: 'require("process")'
- },
- resolve: {
- alias: {
- vue$: path.resolve('..', 'node_modules', 'vue', 'dist', 'vue.esm.js')
- },
- modules: [
- path.resolve('..', 'node_modules'),
- path.resolve('..', 'common', 'modules')
- ]
- },
- plugins: [
- new webpack.DefinePlugin({
- PRODUCTION: JSON.stringify(true)
- }),
- new VueLoaderPlugin()
- ]
-};
diff --git a/editor/package.json b/editor/package.json
index 0e692209..c60c3397 100644
--- a/editor/package.json
+++ b/editor/package.json
@@ -5,7 +5,7 @@
"version": "0.4.0",
"homepage": "https://betterdiscord.net",
"license": "MIT",
- "main": "dist/csseditor.js",
+ "main": "dist/editor.js",
"contributors": [
"Jiiks",
"Pohky"
diff --git a/gulpfile.babel.js b/gulpfile.babel.js
index 10b89c8b..1f1c3332 100644
--- a/gulpfile.babel.js
+++ b/gulpfile.babel.js
@@ -4,6 +4,7 @@ import del from 'del';
import copy from 'gulp-copy';
import rename from 'gulp-rename';
import inject from 'gulp-inject-string';
+import replace from 'gulp-replace';
import copydeps from './scripts/copydeps';
import file from 'gulp-file';
import editjson from 'gulp-json-editor';
@@ -14,10 +15,10 @@ import editorpkg from './editor/package';
// core-release >
-gulp.task('core-main', function () {
+gulp.task('core-main', function() {
return pump([
gulp.src('core/dist/main.js'),
- inject.after(`'use strict';\n`, 'const PRODUCTION = true;\n'),
+ replace('/*PRODUCTION*/', 'const PRODUCTION = true;'),
rename(`core.${corepkg.version}.js`),
gulp.dest('release/core')
]);
@@ -36,27 +37,34 @@ gulp.task('core-pkg', function() {
]);
});
-gulp.task('core-modules', function () {
+gulp.task('core-modules', function() {
return pump([
gulp.src('core/dist/modules/**/*'),
copy('release/core', { prefix: 2 })
]);
});
-gulp.task('core-sparkplug', function () {
+gulp.task('core-sparkplug', function() {
return pump([
gulp.src('core/dist/sparkplug.js'),
gulp.dest('release/core')
]);
});
-gulp.task('core-release', gulp.parallel('core-main', 'core-pkg', 'core-sparkplug', 'core-modules'));
+gulp.task('core-extras', function() {
+ return pump([
+ gulp.src(['core/src/csp.json']),
+ gulp.dest('release/core')
+ ]);
+});
+
+gulp.task('core-release', gulp.parallel('core-main', 'core-pkg', 'core-sparkplug', 'core-modules', 'core-extras'));
// < core-release
// client
-gulp.task('client-main', function () {
+gulp.task('client-main', function() {
return pump([
gulp.src('client/dist/*.client-release.js'),
rename(`client.${clientpkg.version}.js`),
@@ -76,7 +84,7 @@ gulp.task('client-pkg', function() {
]);
});
-gulp.task('client-sparkplug', function () {
+gulp.task('client-sparkplug', function() {
return pump([
gulp.src('core/dist/sparkplug.js'),
gulp.dest('release/client')
@@ -87,7 +95,7 @@ gulp.task('client-release', gulp.parallel('client-main', 'client-pkg', 'client-s
// Editor
-gulp.task('editor-main', function () {
+gulp.task('editor-main', function() {
return pump([
gulp.src('editor/dist/editor.release.js'),
rename(`editor.${editorpkg.version}.js`),
@@ -95,10 +103,10 @@ gulp.task('editor-main', function () {
]);
});
-gulp.task('editor-pkg', function () {
+gulp.task('editor-pkg', function() {
return pump([
gulp.src('editor/package.json'),
- editjson(function (pkg) {
+ editjson(function(pkg) {
pkg.main = `editor.${editorpkg.version}.js`;
delete pkg.scripts;
return pkg;
@@ -118,18 +126,18 @@ gulp.task('node-modules', function() {
]);
});
-gulp.task('node-sass-bindings', gulp.series(function () {
+gulp.task('node-sass-bindings', gulp.series(function() {
return del(['release/node_modules/node-sass/vendor']);
-}, function () {
+}, function() {
return pump([
gulp.src('other/node_sass_bindings/**/*'),
copy('release/core/node_modules/node-sass/vendor', { prefix: 2 })
]);
}));
-gulp.task('keytar-bindings', gulp.series(function () {
+gulp.task('keytar-bindings', gulp.series(function() {
return del(['release/node_modules/keytar/build']);
-}, function () {
+}, function() {
return pump([
gulp.src('other/keytar/**/*'),
copy('release/core/node_modules/keytar/build/Release', { prefix: 2 })
@@ -144,4 +152,4 @@ gulp.task('del-release', function() {
gulp.task('dependencies', gulp.series('node-modules', gulp.parallel('node-sass-bindings', 'keytar-bindings')));
gulp.task('build-release', gulp.parallel('core-release', 'client-release', 'editor-release', 'dependencies'));
-gulp.task('release', gulp.series('del-release', 'build-release'));
\ No newline at end of file
+gulp.task('release', gulp.series('del-release', 'build-release'));
diff --git a/other/keytar/keytar.node/keytar-4.4.1/win32-ia32-69.node b/other/keytar/keytar.node/keytar-4.4.1/win32-ia32-69.node
new file mode 100644
index 00000000..6d726e46
Binary files /dev/null and b/other/keytar/keytar.node/keytar-4.4.1/win32-ia32-69.node differ
diff --git a/other/node_sass_bindings/win32-ia32-69/binding.node b/other/node_sass_bindings/win32-ia32-69/binding.node
new file mode 100644
index 00000000..3dfbc1e2
Binary files /dev/null and b/other/node_sass_bindings/win32-ia32-69/binding.node differ
diff --git a/package-lock.json b/package-lock.json
index facf7bc9..e198080c 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "betterdiscord",
- "version": "2.0.0-beta",
+ "version": "2.0.0-beta.4",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@@ -1583,6 +1583,15 @@
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
"integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ=="
},
+ "axios": {
+ "version": "0.18.0",
+ "resolved": "https://registry.npmjs.org/axios/-/axios-0.18.0.tgz",
+ "integrity": "sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=",
+ "requires": {
+ "follow-redirects": "^1.3.0",
+ "is-buffer": "^1.1.5"
+ }
+ },
"babel-loader": {
"version": "8.0.5",
"resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.0.5.tgz",
@@ -1776,6 +1785,12 @@
"underscore": "~1.4.4"
}
},
+ "binaryextensions": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/binaryextensions/-/binaryextensions-2.1.2.tgz",
+ "integrity": "sha512-xVNN69YGDghOqCCtA6FI7avYrr02mTJjOgB0/f1VPD3pJC8QEvjTKWc4epDx8AqxxA75NI0QpVM2gPJXUbE4Tg==",
+ "dev": true
+ },
"bl": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz",
@@ -3022,6 +3037,12 @@
"object.defaults": "^1.1.0"
}
},
+ "easy-stack": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/easy-stack/-/easy-stack-1.0.0.tgz",
+ "integrity": "sha1-EskbMIWjfwuqM26UhurEv5Tj54g=",
+ "dev": true
+ },
"ecc-jsbn": {
"version": "0.1.2",
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
@@ -3031,6 +3052,12 @@
"safer-buffer": "^2.1.0"
}
},
+ "editions": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/editions/-/editions-1.3.4.tgz",
+ "integrity": "sha512-gzao+mxnYDzIysXKMQi/+M1mjy/rjestjg6OPoYTtI+3Izp23oiGZitsl9lPDPiTGXbcSIk1iJWhliSaglxnUg==",
+ "dev": true
+ },
"editorconfig": {
"version": "0.15.2",
"resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.2.tgz",
@@ -3706,6 +3733,12 @@
"es5-ext": "~0.10.14"
}
},
+ "event-pubsub": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/event-pubsub/-/event-pubsub-4.3.0.tgz",
+ "integrity": "sha512-z7IyloorXvKbFx9Bpie2+vMJKKx1fH1EN5yiTfp8CiLOTptSYy1g8H4yDpGlEdshL1PBiFtBHepF2cNsqeEeFQ==",
+ "dev": true
+ },
"event-stream": {
"version": "3.3.4",
"resolved": "https://registry.npmjs.org/event-stream/-/event-stream-3.3.4.tgz",
@@ -4188,6 +4221,29 @@
"readable-stream": "^2.3.6"
}
},
+ "follow-redirects": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.7.0.tgz",
+ "integrity": "sha512-m/pZQy4Gj287eNy94nivy5wchN3Kp+Q5WgUPNy5lJSZ3sgkVKSYV/ZChMAQVIgx1SqfZ2zBZtPA2YlXIWxxJOQ==",
+ "requires": {
+ "debug": "^3.2.6"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+ "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "ms": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
+ }
+ }
+ },
"for-in": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
@@ -5343,6 +5399,17 @@
"integrity": "sha512-swzbIGb/arEoFK89tPY58vg3Ok1bw+d35PfUNwWqdo7KM4jkmuGA78JiDNqR+JeZFaeeHnRg9N7aihX3YPmsyg==",
"dev": true
},
+ "gulp-replace": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/gulp-replace/-/gulp-replace-1.0.0.tgz",
+ "integrity": "sha512-lgdmrFSI1SdhNMXZQbrC75MOl1UjYWlOWNbNRnz+F/KHmgxt3l6XstBoAYIdadwETFyG/6i+vWUSCawdC3pqOw==",
+ "dev": true,
+ "requires": {
+ "istextorbinary": "2.2.1",
+ "readable-stream": "^2.0.1",
+ "replacestream": "^4.0.0"
+ }
+ },
"gulp-watch": {
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/gulp-watch/-/gulp-watch-5.0.1.tgz",
@@ -6396,6 +6463,17 @@
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
},
+ "istextorbinary": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/istextorbinary/-/istextorbinary-2.2.1.tgz",
+ "integrity": "sha512-TS+hoFl8Z5FAFMK38nhBkdLt44CclNRgDHWeMgsV8ko3nDlr/9UI2Sf839sW7enijf8oKsZYXRvM8g0it9Zmcw==",
+ "dev": true,
+ "requires": {
+ "binaryextensions": "2",
+ "editions": "^1.3.3",
+ "textextensions": "2"
+ }
+ },
"jquery": {
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.3.1.tgz",
@@ -6438,6 +6516,21 @@
"integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==",
"dev": true
},
+ "js-message": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/js-message/-/js-message-1.0.5.tgz",
+ "integrity": "sha1-IwDSSxrwjondCVvBpMnJz8uJLRU=",
+ "dev": true
+ },
+ "js-queue": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/js-queue/-/js-queue-2.0.0.tgz",
+ "integrity": "sha1-NiITz4YPRo8BJfxslqvBdCUx+Ug=",
+ "dev": true,
+ "requires": {
+ "easy-stack": "^1.0.0"
+ }
+ },
"js-tokens": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
@@ -6757,6 +6850,12 @@
"integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=",
"dev": true
},
+ "lodash.endswith": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/lodash.endswith/-/lodash.endswith-4.2.1.tgz",
+ "integrity": "sha1-/tWawXOO0+I27dcGTsRWRIs3vAk=",
+ "dev": true
+ },
"lodash.flatten": {
"version": "4.4.0",
"resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz",
@@ -7355,6 +7454,17 @@
}
}
},
+ "node-ipc": {
+ "version": "9.1.1",
+ "resolved": "https://registry.npmjs.org/node-ipc/-/node-ipc-9.1.1.tgz",
+ "integrity": "sha512-FAyICv0sIRJxVp3GW5fzgaf9jwwRQxAKDJlmNFUL5hOy+W4X/I5AypyHoq0DXXbo9o/gt79gj++4cMr4jVWE/w==",
+ "dev": true,
+ "requires": {
+ "event-pubsub": "4.3.0",
+ "js-message": "1.0.5",
+ "js-queue": "2.0.0"
+ }
+ },
"node-libs-browser": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.0.tgz",
@@ -7908,6 +8018,59 @@
"readable-stream": "^2.1.5"
}
},
+ "parallel-webpack": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/parallel-webpack/-/parallel-webpack-2.3.0.tgz",
+ "integrity": "sha512-RCIDF+YOqyAJeM8NumtOQ8JYjUXexDRIN4slFNfvUp1RxLB1zLeLZMAwlP6s7l9LhuR5xJ2pv8ckIsdESzSqog==",
+ "dev": true,
+ "requires": {
+ "ajv": "^4.9.2",
+ "bluebird": "^3.0.6",
+ "chalk": "^1.1.1",
+ "interpret": "^1.0.1",
+ "lodash.assign": "^4.0.8",
+ "lodash.endswith": "^4.0.1",
+ "lodash.flatten": "^4.2.0",
+ "minimist": "^1.2.0",
+ "node-ipc": "^9.1.0",
+ "pluralize": "^1.2.1",
+ "supports-color": "^3.1.2",
+ "worker-farm": "^1.3.1"
+ },
+ "dependencies": {
+ "ajv": {
+ "version": "4.11.8",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
+ "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=",
+ "dev": true,
+ "requires": {
+ "co": "^4.6.0",
+ "json-stable-stringify": "^1.0.1"
+ }
+ },
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
+ "dev": true
+ },
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
+ "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "dev": true,
+ "requires": {
+ "has-flag": "^1.0.0"
+ }
+ }
+ }
+ },
"param-case": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz",
@@ -8347,6 +8510,28 @@
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
}
+ },
+ "tar-fs": {
+ "version": "1.16.3",
+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.3.tgz",
+ "integrity": "sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw==",
+ "requires": {
+ "chownr": "^1.0.1",
+ "mkdirp": "^0.5.1",
+ "pump": "^1.0.0",
+ "tar-stream": "^1.1.2"
+ },
+ "dependencies": {
+ "pump": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz",
+ "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==",
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ }
+ }
}
}
},
@@ -8473,7 +8658,6 @@
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
- "dev": true,
"requires": {
"end-of-stream": "^1.1.0",
"once": "^1.3.1"
@@ -8849,6 +9033,17 @@
"remove-trailing-separator": "^1.1.0"
}
},
+ "replacestream": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/replacestream/-/replacestream-4.0.3.tgz",
+ "integrity": "sha512-AC0FiLS352pBBiZhd4VXB1Ab/lh0lEgpP+GGvZqbQh8a5cmXVoTe5EX/YeTFArnp4SRGTHh1qCHu9lGs1qG8sA==",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^1.0.3",
+ "object-assign": "^4.0.1",
+ "readable-stream": "^2.0.2"
+ }
+ },
"request": {
"version": "2.88.0",
"resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
@@ -10105,23 +10300,44 @@
}
},
"tar-fs": {
- "version": "1.16.3",
- "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.3.tgz",
- "integrity": "sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.0.tgz",
+ "integrity": "sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA==",
"requires": {
- "chownr": "^1.0.1",
+ "chownr": "^1.1.1",
"mkdirp": "^0.5.1",
- "pump": "^1.0.0",
- "tar-stream": "^1.1.2"
+ "pump": "^3.0.0",
+ "tar-stream": "^2.0.0"
},
"dependencies": {
- "pump": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz",
- "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==",
+ "bl": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-3.0.0.tgz",
+ "integrity": "sha512-EUAyP5UHU5hxF8BPT0LKW8gjYLhq1DQIcneOX/pL/m2Alo+OYDQAJlHq+yseMP50Os2nHXOSic6Ss3vSQeyf4A==",
"requires": {
- "end-of-stream": "^1.1.0",
- "once": "^1.3.1"
+ "readable-stream": "^3.0.1"
+ }
+ },
+ "readable-stream": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.2.0.tgz",
+ "integrity": "sha512-RV20kLjdmpZuTF1INEb9IA3L68Nmi+Ri7ppZqo78wj//Pn62fCoJyV9zalccNzDD/OuJpMG4f+pfMl8+L6QdGw==",
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ },
+ "tar-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.0.1.tgz",
+ "integrity": "sha512-I6OJF7wE62BC6zNPdHDtseK0D0187PBjbKSLYY4ffvVkBM6tyBn2O9plDvVM2229/mozfEL/X3++qSvYYQE2xw==",
+ "requires": {
+ "bl": "^3.0.0",
+ "end-of-stream": "^1.4.1",
+ "fs-constants": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^3.1.1"
}
}
}
@@ -10264,6 +10480,12 @@
"integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
"dev": true
},
+ "textextensions": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/textextensions/-/textextensions-2.4.0.tgz",
+ "integrity": "sha512-qftQXnX1DzpSV8EddtHIT0eDDEiBF8ywhFYR2lI9xrGtxqKN+CvLXhACeCIGbCpQfxxERbrkZEFb8cZcDKbVZA==",
+ "dev": true
+ },
"throttleit": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz",
diff --git a/package.json b/package.json
index fb89baa6..f16a6191 100644
--- a/package.json
+++ b/package.json
@@ -2,7 +2,7 @@
"name": "betterdiscord",
"description": "BetterDiscord",
"author": "Jiiks",
- "version": "2.0.0-beta.3",
+ "version": "2.0.0-beta.4",
"homepage": "https://betterdiscord.net",
"license": "MIT",
"main": "core/dist/main.js",
@@ -17,6 +17,7 @@
"private": false,
"dependencies": {
"asar": "^1.0.0",
+ "axios": "^0.18.0",
"chokidar": "^2.1.2",
"csp-parse": "github:macropodhq/csp-parse",
"deepmerge": "^3.2.0",
@@ -24,7 +25,9 @@
"keytar": "^4.4.1",
"nedb": "^1.8.0",
"node-sass": "^4.11.0",
- "original-fs": "^1.0.0"
+ "original-fs": "^1.0.0",
+ "semver": "^5.6.0",
+ "tar-fs": "^2.0.0"
},
"devDependencies": {
"@babel/core": "^7.3.4",
@@ -51,6 +54,7 @@
"gulp-inject-string": "^1.1.2",
"gulp-json-editor": "^2.5.1",
"gulp-rename": "^1.4.0",
+ "gulp-replace": "^1.0.0",
"gulp-watch": "^5.0.1",
"hash-files": "^1.1.1",
"html-webpack-plugin": "^3.2.0",
@@ -58,6 +62,7 @@
"lodash": "^4.17.11",
"mkdirp": "^0.5.1",
"node-gyp": "^3.8.0",
+ "parallel-webpack": "^2.3.0",
"pump": "^3.0.0",
"request-promise-native": "1.0.5",
"sass-lint": "^1.12.1",
@@ -82,6 +87,8 @@
"watch_core": "npm run watch --prefix core",
"build_editor": "npm run build --prefix editor",
"watch_editor": "npm run watch --prefix editor",
+ "build_all": "parallel-webpack --progress --colors --config=webpack.all.config.js",
+ "watch_all": "parallel-webpack --progress --colors --watch --config=webpack.all.config.js",
"lint": "eslint -f unix client/src core/src editor/src common && npm run sasslint",
"lint_fix": "eslint -f unix client/src core/src",
"sasslint": "sass-lint client/src/styles/**/*.scss -v",
@@ -91,7 +98,8 @@
"package_release": "node scripts/package-release.js",
"gulp_release": "gulp release",
"release": "npm run lint && npm run build_release && gulp release && npm run package_release",
- "update_release": "npm run build_release && gulp build-release",
+ "release_test": "npm run build_release && gulp release",
+ "update_release": "npm run build_release && gulp release",
"inject": "node scripts/inject.js"
}
}
diff --git a/scripts/package-release.js b/scripts/package-release.js
index f69db474..de13c9a3 100644
--- a/scripts/package-release.js
+++ b/scripts/package-release.js
@@ -53,6 +53,7 @@ async function archiveCore(out = './release/core.tar.gz') {
coreArchive.file('./release/core/package.json', { name: 'core/package.json' });
coreArchive.file('./release/core/index.js', { name: 'core/index.js' });
coreArchive.file(`./release/core/${mainFn}`, { name: `core/${mainFn}` });
+ coreArchive.file('./release/core/csp.json', { name: 'core/csp.json' });
coreArchive.file('./release/core/sparkplug.js', { name: 'core/sparkplug.js' });
coreArchive.directory('./release/core/modules', 'core/modules');
coreArchive.directory('./release/core/node_modules', 'core/node_modules');
diff --git a/webpack.all.config.js b/webpack.all.config.js
new file mode 100644
index 00000000..b66dc79a
--- /dev/null
+++ b/webpack.all.config.js
@@ -0,0 +1,28 @@
+const path = require('path');
+
+const editor = require('./editor/webpack.config');
+
+editor.output.path = path.resolve('editor', 'dist');
+editor.entry = path.resolve('editor', editor.entry);
+editor.resolve.alias['vue$'] = path.resolve('node_modules', 'vue', 'dist', 'vue.esm.js');
+editor.resolve.modules = [
+ path.resolve('node_modules'),
+ path.resolve('common', 'modules')
+];
+
+const client = require('./client/webpack.config');
+
+client.output.path = path.resolve('client', 'dist');
+client.entry = path.resolve('client', client.entry);
+client.resolve.alias['vue$'] = path.resolve('node_modules', 'vue', 'dist', 'vue.esm.js');
+client.resolve.modules = [
+ path.resolve('node_modules'),
+ path.resolve('common', 'modules'),
+ path.resolve('client', 'src', 'modules'),
+ path.resolve('client', 'src', 'ui'),
+ path.resolve('client', 'src', 'plugins'),
+ path.resolve('client', 'src', 'structs'),
+ path.resolve('client', 'src', 'builtin')
+];
+
+module.exports = [editor, client];