Skip to content
This repository has been archived by the owner on Jul 31, 2022. It is now read-only.

Commit

Permalink
Alot has changed!
Browse files Browse the repository at this point in the history
- Add the  flag to compile the script to JavaScript
- Move from TSLint and use TypeScript ESLint
- Add ESLint rules to VSCode
- Refractored DatabaseManager and the statistics command
  • Loading branch information
August (Chris) committed Sep 15, 2019
1 parent f0b0fc4 commit a4b6647
Show file tree
Hide file tree
Showing 7 changed files with 204 additions and 144 deletions.
50 changes: 50 additions & 0 deletions .eslintrc.json
@@ -0,0 +1,50 @@
{
"parser": "@typescript-eslint/parser",
"root": true,
"plugins": ["@typescript-eslint"],
"env": {
"es6": true,
"node": true,
"mongo": true
},
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module",
"ecmaFeatures": {
"jsx": true,
"forOf": true,
"spread": true,
"modules": true,
"classes": true,
"generators": true,
"restParams": true,
"regexUFlag": true,
"regexYFlag": true,
"globalReturn": true,
"destructuring": true,
"impliedStrict": true,
"blockBindings": true,
"defaultParams": true,
"octalLiterals": true,
"arrowFunctions": true,
"binaryLiterals": true,
"templateStrings": true,
"superInFunctions": true,
"unicodeCodePointEscapes": true,
"objectLiteralShorthandMethods": true,
"objectLiteralComputedProperties": true,
"objectLiteralDuplicateProperties": true,
"objectLiteralShorthandProperties": true
}
},
"rules": {
"@typescript-eslint/array-type": "error",
"no-duplicate-imports": "error",
"indent": [0, 4],
"semi": "error"
},
"globals": {
"_config": false,
"console": true
}
}
8 changes: 7 additions & 1 deletion .vscode/settings.json
@@ -1,3 +1,9 @@
{
"typescript.tsdk": "node_modules\\typescript\\lib"
"typescript.tsdk": "node_modules\\typescript\\lib",
"eslint.validate": [
{
"language": "typescript",
"autoFix": true
}
]
}
18 changes: 9 additions & 9 deletions package.json
@@ -1,13 +1,14 @@
{
"name": "nino",
"description": "Moderation bot for Discord's hack week entry.",
"version": "0.3.5",
"version": "0.4.0",
"main": "dist/bot.js",
"scripts": {
"build": "rm -fr dist && tsc",
"buildDev": "rm -fr dist && tsc -w",
"build": "yarn lint && rm -fr dist && tsc",
"build:dev": "rm -fr dist && tsc -w",
"main": "yarn build && node dist/bot.js",
"dev": "nodemon dist/bot.js"
"dev": "nodemon dist/bot.js",
"lint": "eslint src --ext .ts --fix"
},
"maintainers": [
"Kyle (dvhe)",
Expand All @@ -18,7 +19,7 @@
],
"dependencies": {
"@augu/immutable": "0.0.5",
"@sentry/integrations": "^5.5.0",
"@sentry/integrations": "5.5.0",
"@sentry/node": "5.6.2",
"common-tags": "1.8.0",
"eris": "0.10.1",
Expand All @@ -39,11 +40,10 @@
"@types/mongoose": "5.5.17",
"@types/ms": "0.7.31",
"@types/node": "12.7.5",
"@typescript-eslint/eslint-plugin": "2.2.0",
"@typescript-eslint/parser": "2.2.0",
"eslint": "6.3.0",
"eslint-config-google": "0.13.0",
"nodemon": "1.19.2",
"tslint": "5.20.0",
"typescript": "3.6.3",
"typescript-tslint-plugin": "0.5.4"
"typescript": "3.6.3"
}
}
62 changes: 22 additions & 40 deletions src/commands/generic/Statistics.ts
Expand Up @@ -2,12 +2,9 @@ import { VERSION as __version__ } from 'eris';
import { stripIndents } from 'common-tags';
import { humanize } from '../../util';
import NinoClient from '../../structures/Client';
import mongoose from 'mongoose';
import Command from '../../structures/Command';
import Context from '../../structures/Context';
import ts from 'typescript';

const version: string = require('../../../package').version;
import GuildModel from '../../models/GuildSchema';

export default class StatisticsCommand extends Command {
constructor(client: NinoClient) {
Expand All @@ -22,9 +19,9 @@ export default class StatisticsCommand extends Command {

getMostUsedCommand() {
const name = Object.keys(this.client.stats.commandUsage)
.map(key => ({ key, uses: this.client.stats.commandUsage[key].size })) // map key array to {key uses} array
.sort((a, b) => b.uses - a.uses) // Sort by uses
[0].key;
.map(key => ({ key, uses: this.client.stats.commandUsage[key].size })) // map key array to {key uses} array
.sort((a, b) => b.uses - a.uses) // Sort by uses
[0].key;

return {
command: name,
Expand All @@ -34,37 +31,22 @@ export default class StatisticsCommand extends Command {
}

async run(ctx: Context) {
const mostUsed = this.getMostUsedCommand();
return ctx.embed(
this
.client
.getEmbed()
.setTitle(`${this.client.user.username}#${this.client.user.discriminator} | Realtime Statistics`)
.setDescription(stripIndents`
**General**
**\`Guilds\`**: ${this.client.guilds.size.toLocaleString()}
**\`Users\`**: ${this.client.users.size.toLocaleString()}
**\`Channels\`**: ${Object.keys(this.client.channelGuildMap).length.toLocaleString()}
**\`Shards\`**: ${this.client.shards.size}
**\`Uptime\`**: ${humanize(Date.now() - this.client.startTime)}
**\`Commands\`**: ${this.client.manager.commands.size}
**Versions**
**\`Eris\`**: v${__version__}
**\`Nino\`**: v${version}
**\`Mongoose\`**: v${mongoose.version}
**\`Node\`**: ${process.version}
**\`TypeScript\`**: v${ts.version}
**Other**
**\`Messages Seen\`**: ${this.client.stats.messagesSeen.toLocaleString()}
**\`Commands Executed\`**: ${this.client.stats.commandsExecuted.toLocaleString()}
**\`Most Used Command\`**: ${mostUsed.command} (${mostUsed.size} executions; ${mostUsed.users} user${mostUsed.users > 1? 's': ''})
`)
.build()
);
const command = this.getMostUsedCommand();
const ping = await this.client.database.admin.ping();

return ctx.send(stripIndents`
\`\`\`prolog
Guilds ~> ${this.client.guilds.size.toLocaleString()}
Users ~> ${this.client.users.size.toLocaleString()}
Channels ~> ${Object.keys(this.client.channelGuildMap).length.toLocaleString()}
Shards [C/T] ~> [${ctx.guild.shard.id}/${this.client.shards.size}]
Uptime ~> ${humanize(Date.now() - this.client.startTime)}
Commands ~> ${this.client.manager.commands.size}
Messages Seen ~> ${this.client.stats.messagesSeen.toLocaleString()}
Commands Executed ~> ${this.client.stats.commandsExecuted.toLocaleString()}
Most Used Command ~> ${command.command} (${command.size} executions)
Database Connection ~> ${ping}ms
\`\`\`
`);
}
}
}
64 changes: 64 additions & 0 deletions src/commands/system/Eval.ts
Expand Up @@ -3,6 +3,16 @@ import NinoClient from '../../structures/Client';
import Command from '../../structures/Command';
import Context from '../../structures/Context';
import EmbedBuilder from '../../structures/EmbedBuilder';
import ts from 'typescript';
import fs from 'fs';

class CompilerError extends Error {
constructor(m: string) {
super(m);

this.name = 'CompilerError';
}
}

export default class EvalCommand extends Command {
constructor(client: NinoClient) {
Expand All @@ -22,7 +32,12 @@ export default class EvalCommand extends Command {
const script = ctx.args.join(' ');
const startTime = Date.now();
let result;

const typescript = ctx.flags.get('ts');
if (typeof typescript === 'string') return ctx.send('Um, I\'m sorry but it\'s just `--ts`');

try {
if (typescript) result = this.compileTypescript(script);
result = eval(script);
const evaluationTime = Date.now() - startTime;
await message.edit({
Expand All @@ -45,4 +60,53 @@ export default class EvalCommand extends Command {
});
}
}

// Stolen from: https://github.com/yamdbf/core/blob/master/src/command/base/EvalTS.ts#L68-L96
compileTypescript(script: string) {
let message!: string;
const file = `${process.cwd()}${require('path').sep}data${require('path').sep}eval_${Date.now()}.ts`;
fs.writeFileSync(file, script);
const program: any = ts.createProgram([file], {
target: ts.ScriptTarget.ESNext,
module: ts.ModuleKind.CommonJS,
lib: ['es2015', 'es2016', 'es2017', 'es2018', 'esnext'],
declaration: false,
strict: true,
noImplicitAny: true,
moduleResolution: ts.ModuleResolutionKind.NodeJs,
allowSyntheticDefaultImports: true,
esModuleInterop: true,
experimentalDecorators: true,
emitDeclarationMetadata: true
});

let diagnostics: (readonly any[]) = ts.getPreEmitDiagnostics(program);
if (diagnostics.length > 0) {
diagnostics = diagnostics.map((data) => {
const txt = ts.flattenDiagnosticMessageText(data.messageText, '\n');
const d = data.file!.getLineAndCharacterOfPosition(data.start!);
return `\n[${d.line + 1};${d.character + 1}]: ${txt} (${data.code})`;
}).filter(d => !d.includes('Cannot find name'));
if (diagnostics.length > 0) message = diagnostics.join('');
}

fs.unlinkSync(file);
if (message) throw new CompilerError(message);

return ts.transpileModule(script, {
compilerOptions: {
target: ts.ScriptTarget.ESNext,
module: ts.ModuleKind.CommonJS,
lib: ['es2015', 'es2016', 'es2017', 'es2018', 'esnext'],
declaration: false,
strict: true,
noImplicitAny: true,
moduleResolution: ts.ModuleResolutionKind.NodeJs,
allowSyntheticDefaultImports: true,
esModuleInterop: true,
experimentalDecorators: true,
emitDeclarationMetadata: true
}
}).outputText;
}
}

0 comments on commit a4b6647

Please sign in to comment.