refactor: rewrite for error handling, logging and disposing

This commit is contained in:
iCrawl 2020-07-16 18:25:05 +02:00
parent ad9dad83e1
commit 99766de53d
No known key found for this signature in database
GPG key ID: 1AB888B16355FBB2
8 changed files with 655 additions and 1388 deletions

45
package-lock.json generated
View file

@ -1,6 +1,6 @@
{ {
"name": "discord-vscode", "name": "discord-vscode",
"version": "3.16.0", "version": "4.0.0",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {
@ -912,9 +912,9 @@
"dev": true "dev": true
}, },
"cacache": { "cacache": {
"version": "15.0.4", "version": "15.0.5",
"resolved": "https://registry.npmjs.org/cacache/-/cacache-15.0.4.tgz", "resolved": "https://registry.npmjs.org/cacache/-/cacache-15.0.5.tgz",
"integrity": "sha512-YlnKQqTbD/6iyoJvEY3KJftjrdBYroCbxxYXzhOzsFLWlp6KX4BOlEf4mTx0cMUfVaTS3ENL2QtDWeRYoGLkkw==", "integrity": "sha512-lloiL22n7sOjEEXdL8NAjTgv9a1u43xICE9/203qonkZUCj5X1UEWIdf2/Y0d6QcCtMzbKQyhrcDbdvlZTs/+A==",
"dev": true, "dev": true,
"requires": { "requires": {
"@npmcli/move-file": "^1.0.1", "@npmcli/move-file": "^1.0.1",
@ -922,7 +922,7 @@
"fs-minipass": "^2.0.0", "fs-minipass": "^2.0.0",
"glob": "^7.1.4", "glob": "^7.1.4",
"infer-owner": "^1.0.4", "infer-owner": "^1.0.4",
"lru-cache": "^5.1.1", "lru-cache": "^6.0.0",
"minipass": "^3.1.1", "minipass": "^3.1.1",
"minipass-collect": "^1.0.2", "minipass-collect": "^1.0.2",
"minipass-flush": "^1.0.5", "minipass-flush": "^1.0.5",
@ -936,6 +936,15 @@
"unique-filename": "^1.1.1" "unique-filename": "^1.1.1"
}, },
"dependencies": { "dependencies": {
"lru-cache": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
"integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
"dev": true,
"requires": {
"yallist": "^4.0.0"
}
},
"mkdirp": { "mkdirp": {
"version": "1.0.4", "version": "1.0.4",
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz",
@ -1461,7 +1470,7 @@
} }
}, },
"discord-rpc": { "discord-rpc": {
"version": "github:discordjs/RPC#df0a9e00b17b86c728e7b43bc2bae2641560a887", "version": "github:discordjs/RPC#69915999307d337688b92f6011ea4961a7f8313e",
"from": "github:discordjs/RPC", "from": "github:discordjs/RPC",
"requires": { "requires": {
"node-fetch": "2.6.0", "node-fetch": "2.6.0",
@ -2864,9 +2873,9 @@
} }
}, },
"lodash": { "lodash": {
"version": "4.17.15", "version": "4.17.19",
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz",
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==",
"dev": true "dev": true
}, },
"lru-cache": { "lru-cache": {
@ -4286,15 +4295,15 @@
} }
}, },
"terser-webpack-plugin": { "terser-webpack-plugin": {
"version": "3.0.6", "version": "3.0.7",
"resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-3.0.6.tgz", "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-3.0.7.tgz",
"integrity": "sha512-z3HLOOPUHkCNGkeEHqqiMAIy1pjpHwS1o+i6Zn0Ws3EAvHJj46737efNNEvJ0Vx9BdDQM83d56qySDJOSORA0A==", "integrity": "sha512-5JqibUOctE6Ou4T00IVGYTQJBOhu24jz0PpqYeitQJJ3hlZY2ZKSwzzuqjmBH8MzbdWMgIefpmHwTkvwm6Q4CQ==",
"dev": true, "dev": true,
"requires": { "requires": {
"cacache": "^15.0.4", "cacache": "^15.0.5",
"find-cache-dir": "^3.3.1", "find-cache-dir": "^3.3.1",
"jest-worker": "^26.0.0", "jest-worker": "^26.1.0",
"p-limit": "^3.0.1", "p-limit": "^3.0.2",
"schema-utils": "^2.6.6", "schema-utils": "^2.6.6",
"serialize-javascript": "^4.0.0", "serialize-javascript": "^4.0.0",
"source-map": "^0.6.1", "source-map": "^0.6.1",
@ -4303,9 +4312,9 @@
}, },
"dependencies": { "dependencies": {
"p-limit": { "p-limit": {
"version": "3.0.1", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.1.tgz", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.0.2.tgz",
"integrity": "sha512-mw/p92EyOzl2MhauKodw54Rx5ZK4624rNfgNaBguFZkHzyUG9WsDzFF5/yQVEJinbJDdP4jEfMN+uBquiGnaLg==", "integrity": "sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg==",
"dev": true, "dev": true,
"requires": { "requires": {
"p-try": "^2.0.0" "p-try": "^2.0.0"

View file

@ -1,7 +1,7 @@
{ {
"name": "discord-vscode", "name": "discord-vscode",
"displayName": "Discord Presence", "displayName": "Discord Presence",
"version": "3.16.0", "version": "4.0.0",
"description": "Update your discord status with the newly added rich presence.", "description": "Update your discord status with the newly added rich presence.",
"private": true, "private": true,
"author": { "author": {
@ -181,7 +181,7 @@
}, },
"dependencies": { "dependencies": {
"bufferutil": "^4.0.1", "bufferutil": "^4.0.1",
"discord-rpc": "discordjs/RPC", "discord-rpc": "github:discordjs/RPC",
"utf-8-validate": "^5.0.2", "utf-8-validate": "^5.0.2",
"vsls": "^1.0.2426" "vsls": "^1.0.2426"
}, },
@ -199,7 +199,7 @@
"eslint-config-prettier": "^6.11.0", "eslint-config-prettier": "^6.11.0",
"eslint-plugin-prettier": "^3.1.4", "eslint-plugin-prettier": "^3.1.4",
"prettier": "^2.0.5", "prettier": "^2.0.5",
"terser-webpack-plugin": "^3.0.6", "terser-webpack-plugin": "^3.0.7",
"ts-loader": "^8.0.1", "ts-loader": "^8.0.1",
"typescript": "^3.9.6", "typescript": "^3.9.6",
"webpack": "^4.43.0", "webpack": "^4.43.0",

View file

@ -8,81 +8,87 @@ import { API } from '../git';
let activityTimer: NodeJS.Timer | undefined; let activityTimer: NodeJS.Timer | undefined;
export default class RPCClient implements Disposable { export default class RPCClient implements Disposable {
public statusBarIcon: StatusBarItem;
public config = workspace.getConfiguration('discord'); public config = workspace.getConfiguration('discord');
public git?: API; public git?: API;
private _rpc: any; private rpc: any;
private readonly _activity = new Activity(this); private readonly activity = new Activity(this);
private readonly _clientId: string; public constructor(private readonly clientId: string, public statusBarIcon: StatusBarItem) {}
public constructor(clientId: string, statusBarIcon: StatusBarItem) {
this._clientId = clientId;
this.statusBarIcon = statusBarIcon;
}
public get client() { public get client() {
return this._rpc; return this.rpc;
} }
public async setActivity(workspaceElapsedTime = false) { public async setActivity(workspaceElapsedTime = false) {
if (!this._rpc) return; if (!this.rpc) return;
const activity = await this._activity.generate(workspaceElapsedTime); const activity = await this.activity.generate(workspaceElapsedTime);
if (!activity) return; if (!activity) return;
Logger.log('Sending activity to Discord.'); Logger.log('Sending activity to Discord.');
this._rpc.setActivity(activity); this.rpc.setActivity(activity);
} }
public async allowSpectate() { public allowSpectate() {
if (!this._rpc) return; if (!this.rpc) return;
Logger.log('Allowed spectating.'); Logger.log('Allowed spectating.');
Logger.log('Sending spectate activity to Discord.'); Logger.log('Sending spectate activity to Discord.');
await this._activity.allowSpectate(); void this.activity.allowSpectate();
} }
public async disableSpectate() { public disableSpectate() {
if (!this._rpc) return; if (!this.rpc) return;
Logger.log('Disabled spectating.'); Logger.log('Disabled spectating.');
await this._activity.disableSpectate(); void this.activity.disableSpectate();
} }
public async allowJoinRequests() { public allowJoinRequests() {
if (!this._rpc) return; if (!this.rpc) return;
Logger.log('Allowed join requests.'); Logger.log('Allowed join requests.');
Logger.log('Sending join activity to Discord.'); Logger.log('Sending join activity to Discord.');
await this._activity.allowJoinRequests(); void this.activity.allowJoinRequests();
} }
public async disableJoinRequests() { public disableJoinRequests() {
if (!this._rpc) return; if (!this.rpc) return;
Logger.log('Disabled join requests.'); Logger.log('Disabled join requests.');
await this._activity.disableJoinRequests(); void this.activity.disableJoinRequests();
} }
public async login() { public async login() {
if (this._rpc) return; if (this.rpc) {
this._rpc = new Client({ transport: 'ipc' }); this.dispose();
Logger.log('Logging into RPC.'); }
this._rpc.once('ready', async () => { this.rpc = new Client({ transport: 'ipc' });
Logger.log('Logging into RPC...');
this.rpc.transport.once('close', () => {
if (!this.config.get<boolean>('enabled')) return;
void this.dispose();
this.statusBarIcon.text = '$(plug) Reconnect to Discord';
this.statusBarIcon.command = 'discord.reconnect';
this.statusBarIcon.tooltip = '';
});
this.rpc.once('ready', async () => {
Logger.log('Successfully connected to Discord.'); Logger.log('Successfully connected to Discord.');
this.statusBarIcon.text = '$(globe) Connected to Discord'; this.statusBarIcon.text = '$(globe) Connected to Discord';
this.statusBarIcon.tooltip = 'Connected to Discord'; this.statusBarIcon.tooltip = 'Connected to Discord';
setTimeout(() => (this.statusBarIcon.text = '$(globe)'), 5000); setTimeout(() => (this.statusBarIcon.text = '$(globe)'), 5000);
if (activityTimer) clearInterval(activityTimer); if (activityTimer) clearInterval(activityTimer);
await this.setActivity(this.config.get<boolean>('workspaceElapsedTime')); void this.setActivity(this.config.get<boolean>('workspaceElapsedTime'));
activityTimer = setInterval(() => { activityTimer = setInterval(() => {
this.config = workspace.getConfiguration('discord'); this.config = workspace.getConfiguration('discord');
void this.setActivity(this.config.get<boolean>('workspaceElapsedTime')); void this.setActivity(this.config.get<boolean>('workspaceElapsedTime'));
}, 10000); }, 1000);
this._rpc.subscribe('ACTIVITY_SPECTATE', async ({ secret }: { secret: string }) => { this.rpc.subscribe('ACTIVITY_SPECTATE', async ({ secret }: { secret: string }) => {
const liveshare = await vsls.getApi(); const liveshare = await vsls.getApi();
if (!liveshare) return; if (!liveshare) return;
try { try {
@ -104,7 +110,7 @@ export default class RPCClient implements Disposable {
// Same here, this is a real nasty race condition that happens inside the discord-rpc module currently // Same here, this is a real nasty race condition that happens inside the discord-rpc module currently
// To circumvent this we need to timeout sending the subscribe events to the discord client // To circumvent this we need to timeout sending the subscribe events to the discord client
setTimeout(() => { setTimeout(() => {
this._rpc.subscribe( this.rpc.subscribe(
'ACTIVITY_JOIN_REQUEST', 'ACTIVITY_JOIN_REQUEST',
async ({ user }: { user: { username: string; discriminator: string } }) => { async ({ user }: { user: { username: string; discriminator: string } }) => {
const val = await window.showInformationMessage( const val = await window.showInformationMessage(
@ -112,13 +118,13 @@ export default class RPCClient implements Disposable {
{ title: 'Accept' }, { title: 'Accept' },
{ title: 'Decline' }, { title: 'Decline' },
); );
if (val && val.title === 'Accept') await this._rpc.sendJoinInvite(user); if (val && val.title === 'Accept') await this.rpc.sendJoinInvite(user);
else await this._rpc.closeJoinRequest(user); else await this.rpc.closeJoinRequest(user);
}, },
); );
}, 1000); }, 1000);
setTimeout(() => { setTimeout(() => {
this._rpc.subscribe('ACTIVITY_JOIN', async ({ secret }: { secret: string }) => { this.rpc.subscribe('ACTIVITY_JOIN', async ({ secret }: { secret: string }) => {
const liveshare = await vsls.getApi(); const liveshare = await vsls.getApi();
if (!liveshare) return; if (!liveshare) return;
try { try {
@ -137,33 +143,28 @@ export default class RPCClient implements Disposable {
const liveshare = await vsls.getApi(); const liveshare = await vsls.getApi();
if (!liveshare) return; if (!liveshare) return;
liveshare.onDidChangeSession(({ session }) => { liveshare.onDidChangeSession(({ session }) => {
if (session.id) return this._activity.changePartyId(session.id); if (session.id) return this.activity.changePartyId(session.id);
return this._activity.changePartyId(); return this.activity.changePartyId();
}); });
liveshare.onDidChangePeers(({ added, removed }) => { liveshare.onDidChangePeers(({ added, removed }) => {
if (added.length) return this._activity.increasePartySize(added.length); if (added.length) return this.activity.increasePartySize(added.length);
else if (removed.length) return this._activity.decreasePartySize(removed.length); else if (removed.length) return this.activity.decreasePartySize(removed.length);
}); });
}); });
this._rpc.transport.once('close', async () => { try {
if (!this.config.get<boolean>('enabled')) return; await this.rpc.login({ clientId: this.clientId });
await this.dispose(); } catch (error) {
this.statusBarIcon.text = '$(plug) Reconnect to Discord'; throw error;
this.statusBarIcon.command = 'discord.reconnect'; }
this.statusBarIcon.tooltip = '';
});
await this._rpc.login({ clientId: this._clientId });
} }
public async dispose() { public dispose() {
this._activity.dispose(); this.activity.dispose();
try { if (this.rpc) this.rpc.destroy();
if (this._rpc) await this._rpc.destroy(); this.rpc = null;
} catch {}
this._rpc = null;
this.statusBarIcon.tooltip = ''; this.statusBarIcon.tooltip = '';
if (activityTimer) clearInterval(activityTimer); if (activityTimer) clearInterval(activityTimer);

File diff suppressed because it is too large Load diff

View file

@ -31,27 +31,25 @@ export async function activate(context: ExtensionContext) {
} }
} }
const enabler = commands.registerCommand('discord.enable', async () => { const enabler = commands.registerCommand('discord.enable', () => {
await rpc.dispose(); rpc.dispose();
void config.update('enabled', true); void config.update('enabled', true);
rpc.config = workspace.getConfiguration('discord'); rpc.config = workspace.getConfiguration('discord');
rpc.statusBarIcon.text = '$(pulse) Connecting to Discord...'; rpc.statusBarIcon.text = '$(pulse) Connecting to Discord...';
rpc.statusBarIcon.show(); rpc.statusBarIcon.show();
await rpc.login(); void rpc.login();
void window.showInformationMessage('Enabled Discord Rich Presence for this workspace.'); void window.showInformationMessage('Enabled Discord Rich Presence for this workspace.');
}); });
const disabler = commands.registerCommand('discord.disable', () => {
const disabler = commands.registerCommand('discord.disable', async () => {
void config.update('enabled', false); void config.update('enabled', false);
rpc.config = workspace.getConfiguration('discord'); rpc.config = workspace.getConfiguration('discord');
await rpc.dispose(); rpc.dispose();
rpc.statusBarIcon.hide(); rpc.statusBarIcon.hide();
void window.showInformationMessage('Disabled Discord Rich Presence for this workspace.'); void window.showInformationMessage('Disabled Discord Rich Presence for this workspace.');
}); });
const reconnecter = commands.registerCommand('discord.reconnect', () => {
const reconnecter = commands.registerCommand('discord.reconnect', async () => {
if (loginTimeout) clearTimeout(loginTimeout); if (loginTimeout) clearTimeout(loginTimeout);
await rpc.dispose(); rpc.dispose();
loginTimeout = setTimeout(() => { loginTimeout = setTimeout(() => {
void rpc.login(); void rpc.login();
if (!config.get('silent')) void window.showInformationMessage('Reconnecting to Discord RPC...'); if (!config.get('silent')) void window.showInformationMessage('Reconnecting to Discord RPC...');
@ -59,28 +57,15 @@ export async function activate(context: ExtensionContext) {
rpc.statusBarIcon.command = 'discord.reconnect'; rpc.statusBarIcon.command = 'discord.reconnect';
}, 1000); }, 1000);
}); });
const disconnect = commands.registerCommand('discord.disconnect', () => {
const disconnect = commands.registerCommand('discord.disconnect', async () => { rpc.dispose();
await rpc.dispose();
rpc.statusBarIcon.text = '$(pulse) Reconnect to Discord'; rpc.statusBarIcon.text = '$(pulse) Reconnect to Discord';
rpc.statusBarIcon.command = 'discord.reconnect'; rpc.statusBarIcon.command = 'discord.reconnect';
}); });
const allowSpectate = commands.registerCommand('discord.allowSpectate', () => rpc.allowSpectate());
const allowSpectate = commands.registerCommand('discord.allowSpectate', async () => { const disableSpectate = commands.registerCommand('discord.disableSpectate', () => rpc.disableSpectate());
await rpc.allowSpectate(); const allowJoinRequests = commands.registerCommand('discord.allowJoinRequests', () => rpc.allowJoinRequests());
}); const disableJoinRequests = commands.registerCommand('discord.disableJoinRequests', () => rpc.disableJoinRequests());
const disableSpectate = commands.registerCommand('discord.disableSpectate', async () => {
await rpc.disableSpectate();
});
const allowJoinRequests = commands.registerCommand('discord.allowJoinRequests', async () => {
await rpc.allowJoinRequests();
});
const disableJoinRequests = commands.registerCommand('discord.disableJoinRequests', async () => {
await rpc.disableJoinRequests();
});
context.subscriptions.push( context.subscriptions.push(
enabler, enabler,
@ -93,22 +78,13 @@ export async function activate(context: ExtensionContext) {
disableJoinRequests, disableJoinRequests,
); );
setTimeout(() => {
const gitExtension = extensions.getExtension<GitExtension>('vscode.git');
if (gitExtension) {
if (gitExtension.isActive) {
rpc.git = gitExtension.exports.getAPI(1);
}
}
}, 5000);
if (!isWorkspaceExcluded && config.get<boolean>('enabled')) { if (!isWorkspaceExcluded && config.get<boolean>('enabled')) {
statusBarIcon.show(); statusBarIcon.show();
try { try {
await rpc.login(); await rpc.login();
} catch (error) { } catch (error) {
Logger.log(`Encountered following error after trying to login:\n${error as string}`); Logger.log(`Encountered following error after trying to login:\n${error as string}`);
await rpc.dispose(); rpc.dispose();
if (!config.get('silent')) { if (!config.get('silent')) {
if (error?.message?.includes('ENOENT')) void window.showErrorMessage('No Discord Client detected!'); if (error?.message?.includes('ENOENT')) void window.showErrorMessage('No Discord Client detected!');
else void window.showErrorMessage(`Couldn't connect to Discord via RPC: ${error as string}`); else void window.showErrorMessage(`Couldn't connect to Discord via RPC: ${error as string}`);
@ -117,10 +93,20 @@ export async function activate(context: ExtensionContext) {
rpc.statusBarIcon.command = 'discord.reconnect'; rpc.statusBarIcon.command = 'discord.reconnect';
} }
} }
const gitExtension = extensions.getExtension<GitExtension>('vscode.git');
if (gitExtension) {
if (gitExtension.isActive) {
rpc.git = gitExtension.exports.getAPI(1);
} else {
const extension = await gitExtension.activate();
rpc.git = extension.getAPI(1);
}
}
} }
export async function deactivate() { export function deactivate() {
await rpc.dispose(); rpc.dispose();
} }
process.on('unhandledRejection', (err) => Logger.log(err as string)); process.on('unhandledRejection', (err) => Logger.log(err as string));

View file

@ -2,7 +2,7 @@ import { basename, parse, sep } from 'path';
import { debug, Disposable, env, window, workspace } from 'vscode'; import { debug, Disposable, env, window, workspace } from 'vscode';
import * as vsls from 'vsls'; import * as vsls from 'vsls';
import RPCClient from '../client/RPCClient'; import RPCClient from '../client/RPCClient';
const lang = require('../data/languages.json'); // eslint-disable-line import lang from '../data/languages.json';
const knownExtentions: { [key: string]: { image: string } } = lang.knownExtentions; const knownExtentions: { [key: string]: { image: string } } = lang.knownExtentions;
const knownLanguages: string[] = lang.knownLanguages; const knownLanguages: string[] = lang.knownLanguages;
@ -39,10 +39,9 @@ interface FileDetail {
export default class Activity implements Disposable { export default class Activity implements Disposable {
private _state: State | null = null; private _state: State | null = null;
private _lastKnownFile = ''; private lastKnownFile = '';
// eslint-disable-next-line no-useless-constructor public constructor(private readonly client: RPCClient) {}
public constructor(public client: RPCClient) {}
public get state() { public get state() {
return this._state; return this._state;
@ -52,7 +51,7 @@ export default class Activity implements Disposable {
let largeImageKey: any = 'vscode-big'; let largeImageKey: any = 'vscode-big';
if (window.activeTextEditor) { if (window.activeTextEditor) {
if (window.activeTextEditor.document.languageId === 'Log') return this._state; if (window.activeTextEditor.document.languageId === 'Log') return this._state;
if (this._state && window.activeTextEditor.document.fileName === this._lastKnownFile) { if (this._state && window.activeTextEditor.document.fileName === this.lastKnownFile) {
return (this._state = { return (this._state = {
...this._state, ...this._state,
details: await this._generateDetails( details: await this._generateDetails(
@ -74,7 +73,7 @@ export default class Activity implements Disposable {
), ),
}); });
} }
this._lastKnownFile = window.activeTextEditor.document.fileName; this.lastKnownFile = window.activeTextEditor.document.fileName;
const filename = basename(window.activeTextEditor.document.fileName); const filename = basename(window.activeTextEditor.document.fileName);
largeImageKey = largeImageKey =
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
@ -238,7 +237,7 @@ export default class Activity implements Disposable {
public dispose() { public dispose() {
this._state = null; this._state = null;
this._lastKnownFile = ''; this.lastKnownFile = '';
} }
private async _generateDetails(debugging: string, editing: string, idling: string, largeImageKey: any) { private async _generateDetails(debugging: string, editing: string, idling: string, largeImageKey: any) {

View file

@ -2,14 +2,12 @@ import { OutputChannel, window } from 'vscode';
// eslint-disable-next-line // eslint-disable-next-line
export default class Logger { export default class Logger {
private static _output?: OutputChannel; private static output?: OutputChannel;
private static _setup() {
this._output = this._output ?? window.createOutputChannel('Discord Presence');
}
public static log(message: string) { public static log(message: string) {
if (!this._output) this._setup(); if (!this.output) {
this._output?.appendLine(message); this.output = window.createOutputChannel('Discord Presence');
}
this.output.appendLine(message);
} }
} }

View file

@ -1,20 +1,25 @@
{ {
"compilerOptions": { "compilerOptions": {
"strict": true, "strict": true,
"module": "commonjs", "moduleResolution": "node",
"target": "es2017",
"lib": [
"esnext",
"esnext.array",
"esnext.asynciterable",
"esnext.intl",
"esnext.symbol"
],
"rootDir": "src",
"outDir": "dist",
"declaration": false, "declaration": false,
"sourceMap": true,
"removeComments": false, "removeComments": false,
"experimentalDecorators": true "alwaysStrict": true,
"pretty": true,
"target": "es2017",
"module": "commonjs",
"lib": [
"esnext"
],
"outDir": "dist",
"sourceRoot": "./",
"sourceMap": true,
"inlineSources": true,
"incremental": true,
"noEmitHelpers": true,
"importHelpers": true,
"skipLibCheck": true,
"esModuleInterop": true,
"resolveJsonModule": true
} }
} }