commit
33567a2cfd
|
@ -11,14 +11,13 @@
|
||||||
import { DOM, BdUI, BdMenu, Modals, Toasts, Notifications, BdContextMenu, DiscordContextMenu } from 'ui';
|
import { DOM, BdUI, BdMenu, Modals, Toasts, Notifications, BdContextMenu, DiscordContextMenu } from 'ui';
|
||||||
import BdCss from './styles/index.scss';
|
import BdCss from './styles/index.scss';
|
||||||
import { Events, Globals, Settings, Database, Updater, ModuleManager, PluginManager, ThemeManager, ExtModuleManager, Vendor, Patcher, MonkeyPatch, ReactComponents, ReactHelpers, ReactAutoPatcher, DiscordApi, BdWebApi, Connectivity, Cache, Reflection, PackageInstaller } from 'modules';
|
import { Events, Globals, Settings, Database, Updater, ModuleManager, PluginManager, ThemeManager, ExtModuleManager, Vendor, Patcher, MonkeyPatch, ReactComponents, ReactHelpers, ReactAutoPatcher, DiscordApi, BdWebApi, Connectivity, Cache, Reflection, PackageInstaller } from 'modules';
|
||||||
import { ClientLogger as Logger, ClientIPC, Utils } from 'common';
|
import { ClientLogger as Logger, ClientIPC, Utils, Axi } from 'common';
|
||||||
import { BuiltinManager, EmoteModule, ReactDevtoolsModule, VueDevtoolsModule, TrackingProtection, E2EE } from 'builtin';
|
import { BuiltinManager, EmoteModule, ReactDevtoolsModule, VueDevtoolsModule, TrackingProtection, E2EE } from 'builtin';
|
||||||
import electron from 'electron';
|
import electron from 'electron';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { setTimeout } from 'timers';
|
|
||||||
|
|
||||||
const tests = typeof PRODUCTION === 'undefined';
|
const tests = typeof PRODUCTION === 'undefined';
|
||||||
const ignoreExternal = true;
|
const ignoreExternal = tests && true;
|
||||||
|
|
||||||
class BetterDiscord {
|
class BetterDiscord {
|
||||||
|
|
||||||
|
@ -39,7 +38,7 @@ class BetterDiscord {
|
||||||
BdWebApi,
|
BdWebApi,
|
||||||
Connectivity,
|
Connectivity,
|
||||||
Cache,
|
Cache,
|
||||||
Logger, ClientIPC, Utils,
|
Logger, ClientIPC, Utils, Axi,
|
||||||
|
|
||||||
plugins: PluginManager.localContent,
|
plugins: PluginManager.localContent,
|
||||||
themes: ThemeManager.localContent,
|
themes: ThemeManager.localContent,
|
||||||
|
|
|
@ -102,7 +102,7 @@ export default new class extends Module {
|
||||||
}
|
}
|
||||||
|
|
||||||
get version() {
|
get version() {
|
||||||
return this.config.version;
|
return this.config.versions.core;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ export default class Module {
|
||||||
}
|
}
|
||||||
|
|
||||||
setState(newState) {
|
setState(newState) {
|
||||||
const oldState = this.state;
|
const oldState = Object.assign({}, this.state);
|
||||||
Object.assign(this.state, newState);
|
Object.assign(this.state, newState);
|
||||||
if (this.stateChanged) this.stateChanged(oldState, newState);
|
if (this.stateChanged) this.stateChanged(oldState, newState);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,81 +8,183 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import Events from './events';
|
import { Notifications } from 'ui';
|
||||||
import Globals from './globals';
|
import { Reflection, Globals } from 'modules';
|
||||||
import { ClientLogger as Logger } from 'common';
|
|
||||||
import request from 'request-promise-native';
|
|
||||||
|
|
||||||
export default new class {
|
import Events from './events';
|
||||||
|
import Module from './imodule';
|
||||||
|
|
||||||
|
export default new class extends Module {
|
||||||
|
|
||||||
|
get updates() { return this.state.updates }
|
||||||
|
get bdUpdates() { return this.state.updates.bd }
|
||||||
|
get error() { return null; }
|
||||||
|
get updatesAvailable() { return this.state.updatesAvailable; }
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
this.updatesAvailable = false;
|
super({
|
||||||
this.latestVersion = undefined;
|
updatesAvailable: false,
|
||||||
this.error = undefined;
|
error: null,
|
||||||
|
updates: { bd: [] },
|
||||||
this.init = this.init.bind(this);
|
updating: false
|
||||||
this.checkForUpdates = this.checkForUpdates.bind(this);
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
bindings() {
|
||||||
* The interval to wait before checking for updates.
|
this.restartNotif = this.restartNotif.bind(this);
|
||||||
*/
|
this.reloadNotif = this.reloadNotif.bind(this);
|
||||||
get interval() {
|
this.startUpdate = this.startUpdate.bind(this);
|
||||||
return 60 * 1000 * 30;
|
this.setUpdateStatus = this.setUpdateStatus.bind(this);
|
||||||
|
this.testUi = this.testUi.bind(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
init() {
|
restartNotif() {
|
||||||
this.updateInterval = setInterval(this.checkForUpdates, this.interval);
|
Notifications.add('Updates Finished!', 'Restart required.', [
|
||||||
|
{
|
||||||
|
text: 'Restart Later',
|
||||||
|
onClick: () => { setTimeout(this.restartNotif, 5 * 60000); return true; }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'Restart Now',
|
||||||
|
onClick: () => {
|
||||||
|
try {
|
||||||
|
const { remote } = Globals.require('electron');
|
||||||
|
window.close();
|
||||||
|
Reflection.module.byProps('showToken', 'hideToken').showToken();
|
||||||
|
remote.app.relaunch();
|
||||||
|
remote.app.exit(0);
|
||||||
|
} catch (err) {
|
||||||
|
console.err(err);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
reloadNotif() {
|
||||||
* Installs an update.
|
Notifications.add('Updates Finished!', 'Reload required.', [
|
||||||
* TODO
|
{
|
||||||
*/
|
text: 'Reload Later',
|
||||||
async update() {
|
onClick: () => { setTimeout(this.reloadNotif, 5 * 60000); return true; }
|
||||||
try {
|
},
|
||||||
await new Promise(resolve => setTimeout(resolve, 5000));
|
{
|
||||||
|
text: 'Reload Now',
|
||||||
this.updatesAvailable = false;
|
onClick: () => {
|
||||||
this.latestVersion = Globals.version;
|
document.location.reload();
|
||||||
Events.emit('update-check-end');
|
}
|
||||||
} catch (err) {
|
}
|
||||||
this.error = err;
|
]);
|
||||||
this.checkForUpdates();
|
|
||||||
throw err;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
events(ipc) {
|
||||||
* Checks for updates.
|
ipc.on('updater-checkForUpdates', () => {
|
||||||
* @return {Promise}
|
if (this.state.updating) return; // We're already updating. Updater should be paused anyways at this point.
|
||||||
*/
|
Events.emit('update-check-start');
|
||||||
async checkForUpdates() {
|
});
|
||||||
if (this.updatesAvailable) return true;
|
|
||||||
Events.emit('update-check-start');
|
|
||||||
Logger.info('Updater', 'Checking for updates');
|
|
||||||
|
|
||||||
try {
|
ipc.on('updater-noUpdates', () => {
|
||||||
const response = await request({
|
if (this.state.updatesAvailable) return; // If for some reason we get this even though we have updates already.
|
||||||
uri: 'https://rawgit.com/JsSucks/BetterDiscordApp/master/package.json',
|
this.setState({
|
||||||
json: true
|
updatesAvailable: false,
|
||||||
|
updates: {}
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
this.latestVersion = response.version;
|
ipc.on('updater-updatesAvailable', (_, updates) => {
|
||||||
Events.emit('update-check-end');
|
console.log(updates);
|
||||||
Logger.info('Updater', `Latest Version: ${response.version} - Current Version: ${Globals.version}`);
|
if (this.state.updating) return; // If for some reason we get more updates when we're already updating
|
||||||
|
updates.bd = updates.bd.map(update => {
|
||||||
|
update.text = `${update.id.charAt(0).toUpperCase()}${update.id.slice(1)}`;
|
||||||
|
update.hint = `Current: ${update.currentVersion} | Latest: ${update.version}`;
|
||||||
|
update.status = {
|
||||||
|
update: true,
|
||||||
|
updating: false,
|
||||||
|
updated: false,
|
||||||
|
error: null
|
||||||
|
};
|
||||||
|
|
||||||
if (this.latestVersion !== Globals.version) {
|
return update;
|
||||||
this.updatesAvailable = true;
|
});
|
||||||
Events.emit('updates-available');
|
this.setState({
|
||||||
return true;
|
updates,
|
||||||
|
updatesAvailable: true
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
ipc.on('updater-updated', (_, info) => {
|
||||||
|
const { reloadRequired, restartRequired } = info;
|
||||||
|
if (restartRequired) {
|
||||||
|
this.restartNotif();
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
if (reloadRequired) {
|
||||||
} catch (err) {
|
this.reloadNotif();
|
||||||
Events.emit('update-check-fail', err);
|
return;
|
||||||
throw err;
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ipc.on('updater-updateFinished', (_, update) => {
|
||||||
|
this.setUpdateStatus(update.id, 'updated', true);
|
||||||
|
});
|
||||||
|
|
||||||
|
ipc.on('updater-updateError', (_, update) => {
|
||||||
|
this.setUpdateStatus(update.id, 'error', update.error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
stateChanged(oldState, newState) {
|
||||||
|
if (!newState.updatesAvailable) return Events.emit('update-check-end');
|
||||||
|
if (!oldState.updatesAvailable && newState.updatesAvailable) {
|
||||||
|
Events.emit('updates-available');
|
||||||
|
Notifications.add('', 'Updates Available!', [
|
||||||
|
{
|
||||||
|
text: 'Ignore',
|
||||||
|
onClick: () => { return true; }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
text: 'Show Updates',
|
||||||
|
onClick: () => {
|
||||||
|
Events.emit('bd-open-menu', 'updater');
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
setUpdateStatus(updateId, statusChild, statusValue) {
|
||||||
|
for (const u of this.bdUpdates) {
|
||||||
|
if (u.id === updateId) {
|
||||||
|
u.status[statusChild] = statusValue;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleUpdate(update) {
|
||||||
|
update.status.update = !update.status.update;
|
||||||
|
}
|
||||||
|
|
||||||
|
async startUpdate() {
|
||||||
|
console.log('start update');
|
||||||
|
const updates = { bd: [] };
|
||||||
|
for (const update of this.bdUpdates) {
|
||||||
|
if (update.status.update) {
|
||||||
|
update.status.updating = true;
|
||||||
|
updates.bd.push(update);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
console.log(updates);
|
||||||
|
this.send('updater-startUpdate', updates);
|
||||||
|
}
|
||||||
|
|
||||||
|
testUi(updates) {
|
||||||
|
this.setState({
|
||||||
|
updates,
|
||||||
|
updatesAvailable: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
import jQuery from 'jquery';
|
import jQuery from 'jquery';
|
||||||
import lodash from 'lodash';
|
import lodash from 'lodash';
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
|
import { Axi } from 'common';
|
||||||
|
|
||||||
import request from 'request-promise-native';
|
import request from 'request-promise-native';
|
||||||
|
|
||||||
|
@ -40,6 +41,8 @@ export default class {
|
||||||
*/
|
*/
|
||||||
static get Vue() { return Vue }
|
static get Vue() { return Vue }
|
||||||
|
|
||||||
|
static get axios() { return Axi.axios }
|
||||||
|
|
||||||
static get request() { return request }
|
static get request() { return request }
|
||||||
|
|
||||||
static get Combokeys() { return Combokeys }
|
static get Combokeys() { return Combokeys }
|
||||||
|
|
|
@ -0,0 +1,9 @@
|
||||||
|
.bd-contentColumn .bd-devview {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 33% 33% 33%;
|
||||||
|
|
||||||
|
.bd-button {
|
||||||
|
font-size: 10px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
}
|
|
@ -10,3 +10,4 @@
|
||||||
@import './kvp';
|
@import './kvp';
|
||||||
@import './collection';
|
@import './collection';
|
||||||
@import './e2ee';
|
@import './e2ee';
|
||||||
|
@import './devview';
|
||||||
|
|
|
@ -3,4 +3,22 @@
|
||||||
margin: 0 0 10px;
|
margin: 0 0 10px;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.bd-settingSwitch {
|
||||||
|
.bd-spinner7 {
|
||||||
|
height: 24px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.bd-updaterStatus {
|
||||||
|
text-align: right;
|
||||||
|
|
||||||
|
&.bd-err {
|
||||||
|
color: $colerr;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.bd-ok {
|
||||||
|
color: $colok;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,10 +20,11 @@
|
||||||
<SidebarItem :item="{text, type: 'header'}" />
|
<SidebarItem :item="{text, type: 'header'}" />
|
||||||
<SidebarItem v-for="i in category" :key="i.id" :item="i" :active="item && i.id === item.id" @click="itemOnClick(i.id)" />
|
<SidebarItem v-for="i in category" :key="i.id" :item="i" :active="item && i.id === item.id" @click="itemOnClick(i.id)" />
|
||||||
</template>
|
</template>
|
||||||
|
<SidebarItem v-if="superSecretMenu" :item="{ _type: 'button', text: 'Super Secret' }" :active="superSecretMenuActive" @click="itemOnClick('superSecretMenu')"/>
|
||||||
</Sidebar>
|
</Sidebar>
|
||||||
|
|
||||||
<div slot="sidebarfooter" class="bd-info">
|
<div slot="sidebarfooter" class="bd-info">
|
||||||
<span class="bd-vtext">v2.0.0a by Jiiks/JsSucks</span>
|
<span class="bd-vtext">{{versionString}}</span>
|
||||||
<div @click="openGithub" v-tooltip="'GitHub'" class="bd-materialButton">
|
<div @click="openGithub" v-tooltip="'GitHub'" class="bd-materialButton">
|
||||||
<MiGithubCircle size="16" />
|
<MiGithubCircle size="16" />
|
||||||
</div>
|
</div>
|
||||||
|
@ -37,7 +38,8 @@
|
||||||
|
|
||||||
<ContentColumn slot="content">
|
<ContentColumn slot="content">
|
||||||
<transition name="bd-contentcolumn" @before-enter="animating++" @after-enter="animating--" @enter-cancelled="animating--" @before-leave="animating++" @after-leave="animating--" @leave-cancelled="animating--">
|
<transition name="bd-contentcolumn" @before-enter="animating++" @after-enter="animating--" @enter-cancelled="animating--" @before-leave="animating++" @after-leave="animating--" @leave-cancelled="animating--">
|
||||||
<div v-if="item" :key="item.id">
|
<SuperSecretView v-if="superSecretMenuActive"/>
|
||||||
|
<div v-else-if="item" :key="item.id">
|
||||||
<template v-if="item.component">
|
<template v-if="item.component">
|
||||||
<component :is="item.component" :SettingsWrapper="SettingsWrapper" />
|
<component :is="item.component" :SettingsWrapper="SettingsWrapper" />
|
||||||
</template>
|
</template>
|
||||||
|
@ -63,11 +65,11 @@
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// Imports
|
// Imports
|
||||||
import { Events, Settings } from 'modules';
|
import { Events, Settings, Globals, Reflection } from 'modules';
|
||||||
import { BdMenuItems } from 'ui';
|
import { BdMenuItems } from 'ui';
|
||||||
import { shell } from 'electron';
|
import { shell } from 'electron';
|
||||||
import { SidebarView, Sidebar, SidebarItem, ContentColumn } from './sidebar';
|
import { SidebarView, Sidebar, SidebarItem, ContentColumn } from './sidebar';
|
||||||
import { SettingsWrapper, SettingsPanel, CssEditorView, PluginsView, ThemesView, UpdaterView, ConnectivityView } from './bd';
|
import { SettingsWrapper, SettingsPanel, CssEditorView, PluginsView, ThemesView, UpdaterView, ConnectivityView, SuperSecretView } from './bd';
|
||||||
import { SvgX, MiGithubCircle, MiWeb, MiClose, MiTwitterCircle } from './common';
|
import { SvgX, MiGithubCircle, MiWeb, MiClose, MiTwitterCircle } from './common';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
@ -78,13 +80,15 @@
|
||||||
items: BdMenuItems.items,
|
items: BdMenuItems.items,
|
||||||
Settings,
|
Settings,
|
||||||
SettingsWrapper,
|
SettingsWrapper,
|
||||||
openMenuHandler: null
|
openMenuHandler: null,
|
||||||
|
superSecretMenu: false,
|
||||||
|
superSecretMenuActive: false
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
props: ['active'],
|
props: ['active'],
|
||||||
components: {
|
components: {
|
||||||
SidebarView, Sidebar, SidebarItem, ContentColumn,
|
SidebarView, Sidebar, SidebarItem, ContentColumn,
|
||||||
SettingsWrapper, SettingsPanel, CssEditorView, PluginsView, ThemesView, UpdaterView, ConnectivityView,
|
SettingsWrapper, SettingsPanel, CssEditorView, PluginsView, ThemesView, UpdaterView, ConnectivityView, SuperSecretView,
|
||||||
MiGithubCircle, MiWeb, MiClose, MiTwitterCircle
|
MiGithubCircle, MiWeb, MiClose, MiTwitterCircle
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -96,10 +100,19 @@
|
||||||
category.push(item);
|
category.push(item);
|
||||||
}
|
}
|
||||||
return categories;
|
return categories;
|
||||||
|
},
|
||||||
|
versionString() {
|
||||||
|
return Globals.version;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
itemOnClick(id) {
|
itemOnClick(id) {
|
||||||
|
if (id === 'superSecretMenu') {
|
||||||
|
this.item = 'supersecretmenu';
|
||||||
|
this.superSecretMenuActive = true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.superSecretMenuActive = false;
|
||||||
this.item = this.items.find(item => item.id === id);
|
this.item = this.items.find(item => item.id === id);
|
||||||
},
|
},
|
||||||
closeContent() {
|
closeContent() {
|
||||||
|
@ -123,6 +136,10 @@
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
Events.on('bd-open-menu', this.openMenuHandler = item => item && this.itemOnClick(this.items.find(i => i === item || i.id === item || i.contentid === item || i.set === item).id));
|
Events.on('bd-open-menu', this.openMenuHandler = item => item && this.itemOnClick(this.items.find(i => i === item || i.id === item || i.contentid === item || i.set === item).id));
|
||||||
|
try {
|
||||||
|
const currentUser = Reflection.module.byName('UserStore').getCurrentUser();
|
||||||
|
this.superSecretMenu = ['81388395867156480', '98003542823944192', '249746236008169473', '284056145272766465', '478559353516064769'].includes(currentUser.id)
|
||||||
|
} catch (err) {}
|
||||||
},
|
},
|
||||||
destroyed() {
|
destroyed() {
|
||||||
if (this.openMenuHandler) Events.off('bd-open-menu', this.openMenuHandler);
|
if (this.openMenuHandler) Events.off('bd-open-menu', this.openMenuHandler);
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
/**
|
||||||
|
* BetterDiscord Developer View Component
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<SettingsWrapper headertext="Super Secret">
|
||||||
|
<div class="bd-flex bd-flexCol bd-devview">
|
||||||
|
<FormButton @click="forceUpdate">Force Update</FormButton>
|
||||||
|
<FormButton @click="debugConfig">Config Debug</FormButton>
|
||||||
|
<FormButton @click="testUpdateUi">Update UI Test</FormButton>
|
||||||
|
</div>
|
||||||
|
</SettingsWrapper>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
|
||||||
|
import SettingsWrapper from './SettingsWrapper.vue';
|
||||||
|
import { FormButton } from '../common';
|
||||||
|
import { Globals, Events, Updater } from 'modules';
|
||||||
|
import { ClientIPC } from 'common';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
};
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
SettingsWrapper,
|
||||||
|
FormButton
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
forceUpdate() {
|
||||||
|
ClientIPC.send('debug-updater-forceUpdate');
|
||||||
|
},
|
||||||
|
debugConfig() {
|
||||||
|
console.log(Globals);
|
||||||
|
},
|
||||||
|
testUpdateUi() {
|
||||||
|
Updater.testUi({
|
||||||
|
'bd': [
|
||||||
|
{
|
||||||
|
'id': 'update',
|
||||||
|
'version': '3.0.0',
|
||||||
|
'currentVersion': '2.0.0',
|
||||||
|
'text': 'Update test',
|
||||||
|
'hint': 'Current: 2.0.0 | Latest: 3.0.0',
|
||||||
|
'status': {
|
||||||
|
'update': true,
|
||||||
|
'updating': false,
|
||||||
|
'updated': false,
|
||||||
|
'error': null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'id': 'updating',
|
||||||
|
'version': '3.0.0',
|
||||||
|
'currentVersion': '2.0.0',
|
||||||
|
'text': 'Updating test',
|
||||||
|
'hint': 'Current: 2.0.0 | Latest: 3.0.0',
|
||||||
|
'status': {
|
||||||
|
'update': true,
|
||||||
|
'updating': true,
|
||||||
|
'updated': false,
|
||||||
|
'error': null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'id': 'updated',
|
||||||
|
'version': '3.0.0',
|
||||||
|
'currentVersion': '2.0.0',
|
||||||
|
'text': 'Updated test',
|
||||||
|
'hint': 'Current: 2.0.0 | Latest: 3.0.0',
|
||||||
|
'status': {
|
||||||
|
'update': true,
|
||||||
|
'updating': true,
|
||||||
|
'updated': true,
|
||||||
|
'error': null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'id': 'error',
|
||||||
|
'version': '3.0.0',
|
||||||
|
'currentVersion': '2.0.0',
|
||||||
|
'text': 'Error test',
|
||||||
|
'hint': 'Current: 2.0.0 | Latest: 3.0.0',
|
||||||
|
'status': {
|
||||||
|
'update': true,
|
||||||
|
'updating': true,
|
||||||
|
'updated': false,
|
||||||
|
'error': 'Failed to update.'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
'haveUpdates': true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,28 @@
|
||||||
|
/**
|
||||||
|
* BetterDiscord Updater Status Component
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="bd-settingSwitch">
|
||||||
|
<div class="bd-title">
|
||||||
|
<h3>{{item.text}}</h3>
|
||||||
|
<h3 class="bd-updaterStatus bd-err" v-if="item.status.error">Update Failed!</h3>
|
||||||
|
<h3 class="bd-updaterStatus bd-ok" v-else-if="item.status.updated">Done</h3>
|
||||||
|
<div class="bd-spinner7" v-else-if="item.status.updating" />
|
||||||
|
<h3 class="bd-updaterStatus" v-else>Unknown</h3>
|
||||||
|
</div>
|
||||||
|
<div class="bd-hint">{{item.hint}}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: ['item']
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -0,0 +1,28 @@
|
||||||
|
/**
|
||||||
|
* BetterDiscord Updater Switch Component
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="bd-settingSwitch">
|
||||||
|
<div class="bd-title">
|
||||||
|
<h3>{{item.text}}</h3>
|
||||||
|
<div class="bd-switchWrapper" @click="() => toggle(item)">
|
||||||
|
<input type="checkbox" class="bd-switchCheckbox" />
|
||||||
|
<div class="bd-switch" :class="{'bd-checked': item.status.update}" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="bd-hint">{{item.hint}}</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
props: ['item', 'toggle']
|
||||||
|
}
|
||||||
|
</script>
|
|
@ -11,19 +11,22 @@
|
||||||
<template>
|
<template>
|
||||||
<SettingsWrapper headertext="Updates">
|
<SettingsWrapper headertext="Updates">
|
||||||
<div class="bd-flex bd-flexCol bd-updaterview">
|
<div class="bd-flex bd-flexCol bd-updaterview">
|
||||||
<div v-if="error" class="bd-formItem">
|
<div class="bd-settingsCategories">
|
||||||
<h5 style="margin-bottom: 10px;">Error installing updates</h5>
|
<div class="bd-settingsCategory" v-if="bdUpdates && bdUpdates.length">
|
||||||
<div class="bd-err bd-preWrap"><div class="bd-pre">{{ error.formatted }}</div></div>
|
<div class="bd-formItem">
|
||||||
<div class="bd-formDivider"></div>
|
<h5>BetterDiscord</h5>
|
||||||
|
</div>
|
||||||
|
<div class="bd-formDivider"></div>
|
||||||
|
<div v-for="update in bdUpdates">
|
||||||
|
<UpdaterStatus :item="update" v-if="update.status.updating" />
|
||||||
|
<UpdaterToggle :item="update" :toggle="() => updater.toggleUpdate(update)" v-else />
|
||||||
|
<div class="bd-formDivider"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="bd-formButton bd-button" @click="update">
|
||||||
|
Update
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template v-if="updatesAvailable">
|
|
||||||
<p>Version {{ newVersion }} is available. You are currently running version {{ currentVersion }}.</p>
|
|
||||||
<FormButton :onClick="install" :loading="updating">Install</FormButton>
|
|
||||||
</template>
|
|
||||||
<template v-else>
|
|
||||||
<p>You're all up to date!</p>
|
|
||||||
</template>
|
|
||||||
</div>
|
</div>
|
||||||
</SettingsWrapper>
|
</SettingsWrapper>
|
||||||
</template>
|
</template>
|
||||||
|
@ -32,7 +35,8 @@
|
||||||
import { Globals, Updater } from 'modules';
|
import { Globals, Updater } from 'modules';
|
||||||
import { ClientLogger as Logger } from 'common';
|
import { ClientLogger as Logger } from 'common';
|
||||||
import SettingsWrapper from './SettingsWrapper.vue';
|
import SettingsWrapper from './SettingsWrapper.vue';
|
||||||
import { FormButton } from '../common';
|
import UpdaterToggle from './UpdaterToggle.vue';
|
||||||
|
import UpdaterStatus from './UpdaterStatus.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() {
|
data() {
|
||||||
|
@ -44,26 +48,29 @@
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
SettingsWrapper,
|
SettingsWrapper,
|
||||||
FormButton
|
UpdaterToggle,
|
||||||
|
UpdaterStatus
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
updatesAvailable() {
|
updatesAvailable() {
|
||||||
return this.updater.updatesAvailable;
|
return this.updater.updatesAvailable;
|
||||||
},
|
},
|
||||||
newVersion() {
|
newVersion() {
|
||||||
return this.updater.latestVersion;
|
return '2.0.0-beta.4';
|
||||||
},
|
},
|
||||||
error() {
|
error() {
|
||||||
return this.updater.error;
|
return this.updater.error;
|
||||||
|
},
|
||||||
|
updates() {
|
||||||
|
return this.updater.updates;
|
||||||
|
},
|
||||||
|
bdUpdates() {
|
||||||
|
return this.updater.bdUpdates;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
async install() {
|
update() {
|
||||||
this.updating = true;
|
this.updater.startUpdate();
|
||||||
try {
|
|
||||||
await this.updater.update();
|
|
||||||
} catch (err) {}
|
|
||||||
this.updating = false;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,5 +4,8 @@ export { default as CssEditorView } from './CssEditor.vue';
|
||||||
export { default as PluginsView } from './PluginsView.vue';
|
export { default as PluginsView } from './PluginsView.vue';
|
||||||
export { default as ThemesView } from './ThemesView.vue';
|
export { default as ThemesView } from './ThemesView.vue';
|
||||||
export { default as UpdaterView } from './UpdaterView.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 BdBadge } from './BdBadge.vue';
|
||||||
export { default as ConnectivityView } from './ConnectivityView.vue';
|
export { default as ConnectivityView } from './ConnectivityView.vue';
|
||||||
|
export { default as SuperSecretView } from './SuperSecretView.vue';
|
||||||
|
|
|
@ -28,7 +28,6 @@ module.exports = {
|
||||||
},
|
},
|
||||||
externals: {
|
externals: {
|
||||||
electron: 'require("electron")',
|
electron: 'require("electron")',
|
||||||
asar: 'require("asar")',
|
|
||||||
fs: 'require("fs")',
|
fs: 'require("fs")',
|
||||||
path: 'require("path")',
|
path: 'require("path")',
|
||||||
util: 'require("util")',
|
util: 'require("util")',
|
||||||
|
|
|
@ -13,7 +13,10 @@ const config = {
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
new webpack.NamedModulesPlugin()
|
new webpack.NamedModulesPlugin()
|
||||||
]
|
],
|
||||||
|
externals: {
|
||||||
|
asar: 'require("asar")'
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = merge(baseconfig, config);
|
module.exports = merge(baseconfig, config);
|
||||||
|
|
|
@ -15,7 +15,10 @@ const config = {
|
||||||
new webpack.DefinePlugin({
|
new webpack.DefinePlugin({
|
||||||
PRODUCTION: JSON.stringify(true)
|
PRODUCTION: JSON.stringify(true)
|
||||||
})
|
})
|
||||||
]
|
],
|
||||||
|
externals: {
|
||||||
|
sparkplug: 'require("./sparkplug")'
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = merge(baseconfig, config);
|
module.exports = merge(baseconfig, config);
|
||||||
|
|
|
@ -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'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -3,3 +3,4 @@ export { default as Filters } from './filters';
|
||||||
export { default as Logger, ClientLogger } from './logger';
|
export { default as Logger, ClientLogger } from './logger';
|
||||||
export { default as ClientIPC } from './bdipc';
|
export { default as ClientIPC } from './bdipc';
|
||||||
export { default as AsyncEventEmitter } from './async-eventemitter';
|
export { default as AsyncEventEmitter } from './async-eventemitter';
|
||||||
|
export { default as Axi } from './axi';
|
||||||
|
|
|
@ -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"
|
||||||
|
]
|
||||||
|
}
|
|
@ -0,0 +1,3 @@
|
||||||
|
React Devtools: sha256-fSHKdpQGCHaIqWP3SpJOuUHrLp49jy4dWHzZ/RBJ/p4=
|
||||||
|
Vue Devtools: sha256-VFJcfKY5B3EBkFDgQnv3CozPwBlZcxwssfLVWlPFfZU=
|
||||||
|
Vue Detector: sha256-l6K+77Z1cmldR9gIvaVWlboF/zr5MXCQHcsEHfnr5TU=
|
|
@ -8,11 +8,24 @@
|
||||||
* LICENSE file in the root directory of this source tree.
|
* LICENSE file in the root directory of this source tree.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/*PRODUCTION*/
|
||||||
const TESTS = typeof PRODUCTION === 'undefined';
|
const TESTS = typeof PRODUCTION === 'undefined';
|
||||||
const TEST_ARGS = () => {
|
const TEST_ARGS = () => {
|
||||||
const _basePath = path.resolve(__dirname, '..', '..');
|
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 {
|
return {
|
||||||
|
coreVersion,
|
||||||
|
clientVersion,
|
||||||
|
editorVersion,
|
||||||
'options': {
|
'options': {
|
||||||
'autoInject': true,
|
'autoInject': true,
|
||||||
'commonCore': true,
|
'commonCore': true,
|
||||||
|
@ -26,7 +39,7 @@ const TEST_ARGS = () => {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
const TEST_EDITOR = true;
|
const TEST_EDITOR = TESTS && true;
|
||||||
|
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import sass from 'node-sass';
|
import sass from 'node-sass';
|
||||||
|
@ -35,21 +48,14 @@ import deepmerge from 'deepmerge';
|
||||||
import ContentSecurityPolicy from 'csp-parse';
|
import ContentSecurityPolicy from 'csp-parse';
|
||||||
import keytar from 'keytar';
|
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 packageJson = require(path.resolve(__dirname, 'package.json'));
|
||||||
const sparkplug = path.resolve(__dirname, 'sparkplug.js');
|
const sparkplug = path.resolve(__dirname, 'sparkplug.js');
|
||||||
|
|
||||||
let configProxy;
|
let configProxy;
|
||||||
|
|
||||||
const CSP = {
|
const CSP = TESTS ? require('../src/csp.json') : require('./csp.json');
|
||||||
'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
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
class Comms {
|
class Comms {
|
||||||
constructor(bd) {
|
constructor(bd) {
|
||||||
|
@ -195,6 +201,8 @@ export class BetterDiscord {
|
||||||
get config() { return this._config ? this._config : (this._config = new Config(this._args)); }
|
get config() { return this._config ? this._config : (this._config = new Config(this._args)); }
|
||||||
get window() { return this.windowUtils ? this.windowUtils.window : undefined; }
|
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 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) {
|
constructor(args) {
|
||||||
if (TESTS) args = TEST_ARGS();
|
if (TESTS) args = TEST_ARGS();
|
||||||
|
@ -209,13 +217,16 @@ export class BetterDiscord {
|
||||||
this.config.compatibility();
|
this.config.compatibility();
|
||||||
|
|
||||||
this.bindings();
|
this.bindings();
|
||||||
this.parseClientPackage();
|
|
||||||
this.extraPaths();
|
this.extraPaths();
|
||||||
|
this.parseClientPackage();
|
||||||
|
this.parseEditorPackage();
|
||||||
|
this.parseCorePackage();
|
||||||
this.database.init();
|
this.database.init();
|
||||||
|
|
||||||
configProxy = () => this.config;
|
configProxy = () => this.config;
|
||||||
const autoInitComms = this.comms;
|
const autoInitComms = this.comms;
|
||||||
const autoInitEditor = this.editor;
|
const autoInitEditor = this.editor;
|
||||||
|
this.updater.start();
|
||||||
this.init();
|
this.init();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,7 +291,7 @@ export class BetterDiscord {
|
||||||
*/
|
*/
|
||||||
parseClientPackage() {
|
parseClientPackage() {
|
||||||
const clientPath = this.config.getPath('client');
|
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 { version } = clientPkg;
|
||||||
const main = TESTS ? 'betterdiscord.client.js' : clientPkg.main;
|
const main = TESTS ? 'betterdiscord.client.js' : clientPkg.main;
|
||||||
this.config.addPath('client_script', `${clientPath}/${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')}`);
|
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
|
* Add extra paths to config
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -16,12 +16,36 @@ export default class Config extends Module {
|
||||||
return this.args.version;
|
return this.args.version;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get versions() {
|
||||||
|
return {
|
||||||
|
core: this.coreVersion,
|
||||||
|
client: this.clientVersion,
|
||||||
|
editor: this.editorVersion
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
get coreVersion() {
|
||||||
|
return this.state.coreVersion;
|
||||||
|
}
|
||||||
|
|
||||||
get clientVersion() {
|
get clientVersion() {
|
||||||
return this.args.clientVersion;
|
return this.state.clientVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
get editorVersion() {
|
||||||
|
return this.state.editorVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
setClientVersion(clientVersion) {
|
setClientVersion(clientVersion) {
|
||||||
this.args.clientVersion = clientVersion;
|
this.state.clientVersion = clientVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
setCoreVersion(coreVersion) {
|
||||||
|
this.state.coreVersion = coreVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
setEditorVersion(editorVersion) {
|
||||||
|
this.state.editorVersion = editorVersion;
|
||||||
}
|
}
|
||||||
|
|
||||||
get paths() {
|
get paths() {
|
||||||
|
@ -41,6 +65,7 @@ export default class Config extends Module {
|
||||||
get config() {
|
get config() {
|
||||||
return {
|
return {
|
||||||
version: this.version,
|
version: this.version,
|
||||||
|
versions: this.versions,
|
||||||
paths: this.paths
|
paths: this.paths
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,3 +4,4 @@ export { default as Config } from './config';
|
||||||
export { default as CSSEditor } from './csseditor';
|
export { default as CSSEditor } from './csseditor';
|
||||||
export { default as Editor } from './editor';
|
export { default as Editor } from './editor';
|
||||||
export { default as Database } from './database';
|
export { default as Database } from './database';
|
||||||
|
export { default as Updater } from './updater';
|
||||||
|
|
|
@ -11,6 +11,9 @@
|
||||||
/**
|
/**
|
||||||
* Base Module that every non-static module should extend.
|
* Base Module that every non-static module should extend.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { default as BDIpc } from './bdipc';
|
||||||
|
|
||||||
export default class Module {
|
export default class Module {
|
||||||
|
|
||||||
constructor(args) {
|
constructor(args) {
|
||||||
|
@ -24,6 +27,7 @@ export default class Module {
|
||||||
init() {
|
init() {
|
||||||
if (this.bindings) this.bindings();
|
if (this.bindings) this.bindings();
|
||||||
if (this.setInitialState) this.setInitialState(this.state);
|
if (this.setInitialState) this.setInitialState(this.state);
|
||||||
|
if (this.events) this.events(BDIpc);
|
||||||
}
|
}
|
||||||
|
|
||||||
set args(t) {}
|
set args(t) {}
|
||||||
|
|
|
@ -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}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -4,6 +4,7 @@ import del from 'del';
|
||||||
import copy from 'gulp-copy';
|
import copy from 'gulp-copy';
|
||||||
import rename from 'gulp-rename';
|
import rename from 'gulp-rename';
|
||||||
import inject from 'gulp-inject-string';
|
import inject from 'gulp-inject-string';
|
||||||
|
import replace from 'gulp-replace';
|
||||||
import copydeps from './scripts/copydeps';
|
import copydeps from './scripts/copydeps';
|
||||||
import file from 'gulp-file';
|
import file from 'gulp-file';
|
||||||
import editjson from 'gulp-json-editor';
|
import editjson from 'gulp-json-editor';
|
||||||
|
@ -14,10 +15,10 @@ import editorpkg from './editor/package';
|
||||||
|
|
||||||
// core-release >
|
// core-release >
|
||||||
|
|
||||||
gulp.task('core-main', function () {
|
gulp.task('core-main', function() {
|
||||||
return pump([
|
return pump([
|
||||||
gulp.src('core/dist/main.js'),
|
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`),
|
rename(`core.${corepkg.version}.js`),
|
||||||
gulp.dest('release/core')
|
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([
|
return pump([
|
||||||
gulp.src('core/dist/modules/**/*'),
|
gulp.src('core/dist/modules/**/*'),
|
||||||
copy('release/core', { prefix: 2 })
|
copy('release/core', { prefix: 2 })
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
|
||||||
gulp.task('core-sparkplug', function () {
|
gulp.task('core-sparkplug', function() {
|
||||||
return pump([
|
return pump([
|
||||||
gulp.src('core/dist/sparkplug.js'),
|
gulp.src('core/dist/sparkplug.js'),
|
||||||
gulp.dest('release/core')
|
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
|
// < core-release
|
||||||
|
|
||||||
// client
|
// client
|
||||||
|
|
||||||
gulp.task('client-main', function () {
|
gulp.task('client-main', function() {
|
||||||
return pump([
|
return pump([
|
||||||
gulp.src('client/dist/*.client-release.js'),
|
gulp.src('client/dist/*.client-release.js'),
|
||||||
rename(`client.${clientpkg.version}.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([
|
return pump([
|
||||||
gulp.src('core/dist/sparkplug.js'),
|
gulp.src('core/dist/sparkplug.js'),
|
||||||
gulp.dest('release/client')
|
gulp.dest('release/client')
|
||||||
|
@ -87,7 +95,7 @@ gulp.task('client-release', gulp.parallel('client-main', 'client-pkg', 'client-s
|
||||||
|
|
||||||
// Editor
|
// Editor
|
||||||
|
|
||||||
gulp.task('editor-main', function () {
|
gulp.task('editor-main', function() {
|
||||||
return pump([
|
return pump([
|
||||||
gulp.src('editor/dist/editor.release.js'),
|
gulp.src('editor/dist/editor.release.js'),
|
||||||
rename(`editor.${editorpkg.version}.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([
|
return pump([
|
||||||
gulp.src('editor/package.json'),
|
gulp.src('editor/package.json'),
|
||||||
editjson(function (pkg) {
|
editjson(function(pkg) {
|
||||||
pkg.main = `editor.${editorpkg.version}.js`;
|
pkg.main = `editor.${editorpkg.version}.js`;
|
||||||
delete pkg.scripts;
|
delete pkg.scripts;
|
||||||
return pkg;
|
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']);
|
return del(['release/node_modules/node-sass/vendor']);
|
||||||
}, function () {
|
}, function() {
|
||||||
return pump([
|
return pump([
|
||||||
gulp.src('other/node_sass_bindings/**/*'),
|
gulp.src('other/node_sass_bindings/**/*'),
|
||||||
copy('release/core/node_modules/node-sass/vendor', { prefix: 2 })
|
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']);
|
return del(['release/node_modules/keytar/build']);
|
||||||
}, function () {
|
}, function() {
|
||||||
return pump([
|
return pump([
|
||||||
gulp.src('other/keytar/**/*'),
|
gulp.src('other/keytar/**/*'),
|
||||||
copy('release/core/node_modules/keytar/build/Release', { prefix: 2 })
|
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('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('build-release', gulp.parallel('core-release', 'client-release', 'editor-release', 'dependencies'));
|
||||||
gulp.task('release', gulp.series('del-release', 'build-release'));
|
gulp.task('release', gulp.series('del-release', 'build-release'));
|
||||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -1583,6 +1583,15 @@
|
||||||
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
|
||||||
"integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ=="
|
"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": {
|
"babel-loader": {
|
||||||
"version": "8.0.5",
|
"version": "8.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.0.5.tgz",
|
||||||
|
@ -1776,6 +1785,12 @@
|
||||||
"underscore": "~1.4.4"
|
"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": {
|
"bl": {
|
||||||
"version": "1.2.2",
|
"version": "1.2.2",
|
||||||
"resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz",
|
"resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz",
|
||||||
|
@ -3037,6 +3052,12 @@
|
||||||
"safer-buffer": "^2.1.0"
|
"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": {
|
"editorconfig": {
|
||||||
"version": "0.15.2",
|
"version": "0.15.2",
|
||||||
"resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.2.tgz",
|
"resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-0.15.2.tgz",
|
||||||
|
@ -4200,6 +4221,29 @@
|
||||||
"readable-stream": "^2.3.6"
|
"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": {
|
"for-in": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
|
||||||
|
@ -5355,6 +5399,17 @@
|
||||||
"integrity": "sha512-swzbIGb/arEoFK89tPY58vg3Ok1bw+d35PfUNwWqdo7KM4jkmuGA78JiDNqR+JeZFaeeHnRg9N7aihX3YPmsyg==",
|
"integrity": "sha512-swzbIGb/arEoFK89tPY58vg3Ok1bw+d35PfUNwWqdo7KM4jkmuGA78JiDNqR+JeZFaeeHnRg9N7aihX3YPmsyg==",
|
||||||
"dev": true
|
"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": {
|
"gulp-watch": {
|
||||||
"version": "5.0.1",
|
"version": "5.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/gulp-watch/-/gulp-watch-5.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/gulp-watch/-/gulp-watch-5.0.1.tgz",
|
||||||
|
@ -6408,6 +6463,17 @@
|
||||||
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
||||||
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
|
"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": {
|
"jquery": {
|
||||||
"version": "3.3.1",
|
"version": "3.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.3.1.tgz",
|
||||||
|
@ -8444,6 +8510,28 @@
|
||||||
"end-of-stream": "^1.1.0",
|
"end-of-stream": "^1.1.0",
|
||||||
"once": "^1.3.1"
|
"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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -8570,7 +8658,6 @@
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
|
||||||
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
|
"integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
|
||||||
"dev": true,
|
|
||||||
"requires": {
|
"requires": {
|
||||||
"end-of-stream": "^1.1.0",
|
"end-of-stream": "^1.1.0",
|
||||||
"once": "^1.3.1"
|
"once": "^1.3.1"
|
||||||
|
@ -8946,6 +9033,17 @@
|
||||||
"remove-trailing-separator": "^1.1.0"
|
"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": {
|
"request": {
|
||||||
"version": "2.88.0",
|
"version": "2.88.0",
|
||||||
"resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
|
"resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
|
||||||
|
@ -10202,23 +10300,44 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"tar-fs": {
|
"tar-fs": {
|
||||||
"version": "1.16.3",
|
"version": "2.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.3.tgz",
|
"resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.0.tgz",
|
||||||
"integrity": "sha512-NvCeXpYx7OsmOh8zIOP/ebG55zZmxLE0etfWRbWok+q2Qo8x/vOR/IJT1taADXPe+jsiu9axDb3X4B+iIgNlKw==",
|
"integrity": "sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"chownr": "^1.0.1",
|
"chownr": "^1.1.1",
|
||||||
"mkdirp": "^0.5.1",
|
"mkdirp": "^0.5.1",
|
||||||
"pump": "^1.0.0",
|
"pump": "^3.0.0",
|
||||||
"tar-stream": "^1.1.2"
|
"tar-stream": "^2.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"pump": {
|
"bl": {
|
||||||
"version": "1.0.3",
|
"version": "3.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz",
|
"resolved": "https://registry.npmjs.org/bl/-/bl-3.0.0.tgz",
|
||||||
"integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==",
|
"integrity": "sha512-EUAyP5UHU5hxF8BPT0LKW8gjYLhq1DQIcneOX/pL/m2Alo+OYDQAJlHq+yseMP50Os2nHXOSic6Ss3vSQeyf4A==",
|
||||||
"requires": {
|
"requires": {
|
||||||
"end-of-stream": "^1.1.0",
|
"readable-stream": "^3.0.1"
|
||||||
"once": "^1.3.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"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10361,6 +10480,12 @@
|
||||||
"integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
|
"integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
|
||||||
"dev": true
|
"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": {
|
"throttleit": {
|
||||||
"version": "0.0.2",
|
"version": "0.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz",
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
"private": false,
|
"private": false,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"asar": "^1.0.0",
|
"asar": "^1.0.0",
|
||||||
|
"axios": "^0.18.0",
|
||||||
"chokidar": "^2.1.2",
|
"chokidar": "^2.1.2",
|
||||||
"csp-parse": "github:macropodhq/csp-parse",
|
"csp-parse": "github:macropodhq/csp-parse",
|
||||||
"deepmerge": "^3.2.0",
|
"deepmerge": "^3.2.0",
|
||||||
|
@ -24,7 +25,9 @@
|
||||||
"keytar": "^4.4.1",
|
"keytar": "^4.4.1",
|
||||||
"nedb": "^1.8.0",
|
"nedb": "^1.8.0",
|
||||||
"node-sass": "^4.11.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": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.3.4",
|
"@babel/core": "^7.3.4",
|
||||||
|
@ -51,6 +54,7 @@
|
||||||
"gulp-inject-string": "^1.1.2",
|
"gulp-inject-string": "^1.1.2",
|
||||||
"gulp-json-editor": "^2.5.1",
|
"gulp-json-editor": "^2.5.1",
|
||||||
"gulp-rename": "^1.4.0",
|
"gulp-rename": "^1.4.0",
|
||||||
|
"gulp-replace": "^1.0.0",
|
||||||
"gulp-watch": "^5.0.1",
|
"gulp-watch": "^5.0.1",
|
||||||
"hash-files": "^1.1.1",
|
"hash-files": "^1.1.1",
|
||||||
"html-webpack-plugin": "^3.2.0",
|
"html-webpack-plugin": "^3.2.0",
|
||||||
|
@ -94,7 +98,8 @@
|
||||||
"package_release": "node scripts/package-release.js",
|
"package_release": "node scripts/package-release.js",
|
||||||
"gulp_release": "gulp release",
|
"gulp_release": "gulp release",
|
||||||
"release": "npm run lint && npm run build_release && gulp release && npm run package_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"
|
"inject": "node scripts/inject.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/package.json', { name: 'core/package.json' });
|
||||||
coreArchive.file('./release/core/index.js', { name: 'core/index.js' });
|
coreArchive.file('./release/core/index.js', { name: 'core/index.js' });
|
||||||
coreArchive.file(`./release/core/${mainFn}`, { name: `core/${mainFn}` });
|
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.file('./release/core/sparkplug.js', { name: 'core/sparkplug.js' });
|
||||||
coreArchive.directory('./release/core/modules', 'core/modules');
|
coreArchive.directory('./release/core/modules', 'core/modules');
|
||||||
coreArchive.directory('./release/core/node_modules', 'core/node_modules');
|
coreArchive.directory('./release/core/node_modules', 'core/node_modules');
|
||||||
|
|
Loading…
Reference in New Issue