Giter Club home page Giter Club logo

klasa's Introduction

Klasa

Discord npm npm Build Status Total alerts Dependabot Status David Patreon

Let's stop reinventing the wheel, and start coding the bots of our dreams!

Klasa is an OOP discord.js bot framework which aims to be the most feature complete, while feeling like a consistent extension of discord.js.

Originally based on Komada, Klasa has become a ship of Theseus, keeping many similarities with the former framework but with many enhancements and extra features.

What's with the name?

Following suit from Komada (the Croatian word for "pieces"), Klasa is the Croatian word for "class". By the same token, Klasa is modular, and each module is a piece of a puzzle you use to build your own bot. And you can replace, enhance, reload or remove these pieces; the difference is that Klasa uses classes.

Features

  • Abstracted database handler, works with any database, or atomically written JSON (by default).
  • Easy and powerful command system, featuring usage string, dependent arguments, and custom types.
  • Easy and powerful to configure the permission levels system.
  • Easy to create your own pieces and structures!
  • Editable commands with quoted string support and custom parameter delimiter.
  • Flag arguments.
  • Full OOP and hot-reloadable pieces.
  • Full personalizable configuration system that can serve for much more than just guilds.
  • Incredibly fast loading (~100ms) with deep loading for commands.
  • Per-command cooldowns with bucket support and easy to configure.
  • Many different pieces and standalone utils to help you build the bot of your dreams!
    • Commands: The most basic piece, they run when somebody types the prefix and the command name or any of its aliases.
    • Events: Hot-reloadable structures for events, with internal error handling.
    • Extendables: Easily extend Klasa or discord.js.
    • Finalizers: Structures that run after successful command run.
    • Inhibitors: Middleware that can stop a command from running (blacklist, permissions...).
    • Languages: Easy internationalization support for your bot!
    • Monitors: Watch every single message your bot receives! They're perfect for no-mention-spam, swear word filter, and so on!
    • Providers: You can have one, or more, they're interfaces for the settings system and ensures the data is written correctly!
    • Serializers: These allow you to change how the Settings system reads, writes, and displays information.
    • Tasks: Pieces that handle scheduled tasks.

Time to get started!

See the following tutorial on how to get started using Klasa.

See also:

klasa's People

Contributors

bdistin avatar dependabot-preview[bot] avatar dependabot[bot] avatar devyukine avatar dolliwyx avatar dwigoric avatar favna avatar gc avatar greenkeeper[bot] avatar hellpie avatar imurx avatar kenany avatar kyranet avatar mcumbers avatar mrjacz avatar officialpiyush avatar ognova avatar pandraghon avatar pedall avatar pyrotechniac avatar quantumlyy avatar ruintd avatar shaybox avatar skillz4killz avatar soumil-07 avatar szephyr avatar tech6hutch avatar tylertron1998 avatar unseenfaith avatar vladfrangu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

klasa's Issues

Bug: having an unknown argument type will cause bot to make an infinite loop

In usage, if I was todo <Command:somerandomthing> and run the command console would get spammed with unknown argument type and spam till getting a Javascript stack trace (infinite loop) https://github.com/dirigeants/klasa/blob/master/src/lib/structures/CommandMessage.js#L138 basically what happening is this.client.emit('warn', 'Unknown Argument Type encountered'); return this.multiPossibles(++possible, validated); here it emits warn event then runs the multiPossibles function again causing an infinite loop

Proposal: literal strings in command usage strings

What I mean

in usage strings, you can currently only have optional or required flags in usage but what I mean is having a string in a usage like <reminder:string> in <Time:time> so the command format would be prefix remind me to bug ao about this proposal in 1 hour just like Skyra's reminder command

Examples

usage: "<reminder:string> in <time:time>"

Behaviour

The command to throw some string if in the literal string isn't there this could also be wrapped in <in> or [in] making it required or optional

Version 10 of node.js has been released

Version 10 of Node.js (code name Dubnium) has been released! 🎊

To see what happens to your code in Node.js 10, Greenkeeper has created a branch with the following changes:

  • Added the new Node.js version to your .travis.yml
  • The new Node.js version is in-range for the engines in 1 of your package.json files, so that was left alone

If you’re interested in upgrading this repo to Node.js 10, you can open a PR with these changes. Please note that this issue is just intended as a friendly reminder and the PR as a possible starting point for getting your code running on Node.js 10.

More information on this issue

Greenkeeper has checked the engines key in any package.json file, the .nvmrc file, and the .travis.yml file, if present.

  • engines was only updated if it defined a single version, not a range.
  • .nvmrc was updated to Node.js 10
  • .travis.yml was only changed if there was a root-level node_js that didn’t already include Node.js 10, such as node or lts/*. In this case, the new version was appended to the list. We didn’t touch job or matrix configurations because these tend to be quite specific and complex, and it’s difficult to infer what the intentions were.

For many simpler .travis.yml configurations, this PR should suffice as-is, but depending on what you’re doing it may require additional work or may not be applicable at all. We’re also aware that you may have good reasons to not update to Node.js 10, which is why this was sent as an issue and not a pull request. Feel free to delete it without comment, I’m a humble robot and won’t feel rejected 🤖


FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Proposal: Increment method for SG

An increment method for SG to add/remove numbers from SG Configs.:

// Increment by 1
this.client.configs.increment('commandsUsed', 1);
// Decrement by 1
this.client.configs.increment('commandsUsed', -1);

Current Method of doing this:

// Increment by 1
this.client.configs.update('commandsUsed', this.client.configs.commandsUsed + 1);
// Decrement by 1
this.client.configs.update('commandsUsed', this.client.configs.commandsUsed - 1);

Databases have built-in methods for incrementing which might help in implementing this in providers. MongoDB
RethinkDB

Benefits: Shorter and simpler. Perhaps faster?
Use cases: experience systems, analytics and counters.

Duration.toNow() bugs out on certain timestamps or Date objects

Describe the issue

When Duration#toNow is used on Date objects or timestamps earlier than Date.now(), it returns seconds always.

Code or steps to reproduce

  1. Put a timestamp higher than Date.now() on the first parameter of Duration#toNow()

Expected an actual behaviour

Return the actual Duration, returned seconds instead.

Further details

  • discord.js version: master branch; commit: 745669a
  • node.js version: 10.0.0
  • Klasa version: master branch; commit: f58681d
  • I have modified core files.
  • I have tested the issue on latest master. Commit hash:

An in-range update of @types/node is breaking the build 🚨

Version 9.4.0 of @types/node was just published.

Branch Build failing 🚨
Dependency @types/node
Current Version 9.3.0
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

@types/node is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • continuous-integration/travis-ci/push The Travis CI build failed Details

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Bug: Prompting with cmdEditing

Describe the issue

When KlasaClientOptions.cmdEditing is set to true and command prompt are enabled (formerly known as KlasaClientOptions.cmdPrompt before the refactor), Klasa identifies message edits as new messages, therefore, prompts will identify command edits as the response (which is unwanted most of the time).

Proposal: To fix this issue, we should check if the message received is the same as the one that triggered the prompt. In that case, return an invalid value (i.e. null). As throwing will be (in most cases) identified as the lack of a response. This will be handled by the developer (a notice should be made in the documentation via the JSDoc).

If the message is edited during Usage's prompt, Klasa should cancel the current command execution and re-parse it. That way, when you do:

s!conf set prefix

You'll be prompted by Usage asking for the value to set. And then you edit it to:

s!conf set prefix m!

That'll identify s!conf set prefix m! as the accepted value, in this case, making that the new prefix (in practice this will error as there's a maximum number of characters in the schema) and will run the same command but with m! as the value. This is pretty dangerous in some cases as, related to #180, ratelimits aren't applied during command parsing but after successful command run, so you could call the command multiple times with the prompt and edit them later, causing a fatal issue.

To counter this issue, I propose prompt cancellation when the captured message in Message#prompt() is the same one as the message that called the prompt.

Further details

  • discord.js version: master
  • node.js version: 9.3.0
  • Klasa version: 0.5.0-dev
  • I have modified core files.
  • I have tested the issue on latest master.

Command capitalization

When using commands, they are case insensitive. When using the help command, however, you must use exact case for the command you want help on.

Where the prefix is +:

+Ping
(Works)

+Help Ping
(It can't find the command...not that it tells you that. It sends you the entire list of commands, but I digress)

I am proposing that the cmd ArgResolver be changed to allow this.

[TYPO] Mistake into UnderstandingPermissionLevel.md

Hi,

I've just spotted a little missing parenthesis ')' into the UnderstandingPermissionLevel tutorial.

On the second example (the one showing how to override the defaultPermissionLevels).

Not sure if it's useful but I made a fix here:
#34

Permission levels

is there a client option that would let the owner set a custom amount of level above 10.

Conf command breaks when having a piece in a SchemaFolder

Describe the issue

Having SchemaPiece on a SchemaFolder breaks conf get when trying to access the folder, conf get SchemaFolder#SchemaPiece will work just as fine.

Code or steps to reproduce

  1. Create a SchemaFolder
  2. Create a SchemaPiece with type as TextChannel
  3. Run conf get <SchemaFolder>

Expected an actual behaviour

  • show the SchemaFolder with the piece properly

Further details

Guide/Tutorials Improvements

The docs are still far from perfect, and we would like feedback from our developers to help us improving them before Klasa 1.0.0 release.

Between the issues we could notice:

  • Some parts are not correctly clarified, causing confusions to our new developers.
  • The learning curve isn't fully normalized and starting with Klasa is way very hard for many new developers. For the easiness we give, and with the consistency we keep with discord.js, this should not be an issue, but in the current state, it is, perhaps we need to show this to our users.
  • Lack of use-cases of Klasa, "Building Your Bot" guides, etc. This affects user retention, and we would like to help them with better examples.
  • Lack of examples, we have many many lines of code, whilst they are fully documented, they do not provide good examples.

Typings Bug

Describe the issue

It isn't a huge breaking bug, but something I thought worth mentioning. Honestly, i am not even sure if this is something that can even be fixed.

Typings automatically begin saying BOTNAME is typing... however, it does not take into consideration where the bot is sending the message. For example, if someone runs a command in a channel the bot will say the typings BUT that command actually sends a message in another channel. Its confusing as it seems to cause users to think the bot has broke until they realize oh the message came here.

P.S. This is not breaking just something to make it less inconvenient in those rare circumstances.

Code or steps to reproduce

1) Enable Typings
2) Run a command that sends a message to different channel 

Expected an actual behaviour

Typings should occur on the channel where the bot types.

Further details

  • discord.js version: latest
  • node.js version: 9+
  • Klasa version: latest
  • I have modified core files.
  • I have tested the issue on latest master. Commit hash:

Write a tutorial for the new RichDisplay and further reading tutorial for RichMenu

By the time HactoberFest begins, RichDisplay and RichMenus should be merged into master. It would be great for someone to write tutorials for using them (like the other docs tutorials you can find in the ./tutorials folder).

The tutorials should include a general overview, basic implementation with explanation of parameters, and creative examples of use. The RichMenu should have it's own tutorial as a child of RichDisplay (RichMenu extends RichDisplay) highlighting the similarities and differences, and it's own examples of use.

Please be sure to create your pull request after the first of October so your pr counts for HactoberFest. More details about HactoberFest

Edit: The RichDisplay Tutorial has been completed, and merged. A RichMenu tutorial is still wanted.

An in-range update of markdownlint-cli is breaking the build 🚨

Version 0.8.2 of markdownlint-cli was just published.

Branch Build failing 🚨
Dependency markdownlint-cli
Current Version 0.8.1
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

markdownlint-cli is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • continuous-integration/travis-ci/push The Travis CI build failed Details

Commits

The new version differs by 4 commits.

  • 081d1f2 Bump version 0.8.2
  • d9f6bf6 Merge pull request #37 from mroderick/patch-1
  • ce3f44d Fix #36: Update deep-extend and rc
  • f847068 Move output of --output tests outside test directory to avoid race condition in tests (fixes #34).

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

An in-range update of @types/node is breaking the build 🚨

☝️ Greenkeeper’s updated Terms of Service will come into effect on April 6th, 2018.

Version 9.6.1 of @types/node was just published.

Branch Build failing 🚨
Dependency @types/node
Current Version 9.6.0
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

@types/node is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • continuous-integration/travis-ci/push The Travis CI build failed Details

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Proposal: Cleaner way to change the console colors

Describe the proposal

Currently, changing the colors for the KlasaConsole is, tedious. With code like this

new Client({
    console: {
        colors: {
            [event]: {
                time: {
                    background: "green",
                },
            },
        },
    },
});

looking quite bad.

This proposal is a way to either re-use the already existing Colors class, or another class, to be able to do something more like

new Client({
    console: {
        colors: {
            [event]: {
                time: new Colors({ background: "green", text: "white", style: "underline" }),
                message: new Colors({ background: "white", text: "black" }),
            },
        },
    },
});

This looks way cleaner, and more concise in my opinion., and doesn't go extremely deep in the client options. (something eslint will appreciate if you have the depth rule configured.)

In the given example, [event] is an actual event name, like log or warn

Proposal: Default extendables' appliesTo to extendables/subfolder

Describe the proposal

When you have many extendables, for different classes, I bet it gets pretty disorganized. You can prefix their filenames with the class name, e.g., userProfile.js, but then you have to explicitly specify the property/method name in each one.

I'm proposing that subfolders in the ./extendables/ folder be used as the appliesTo arg by default, so that users can then make the filename the name of the property/method, for simplicity and for better organization.

Rationale

Commands have categories, which are useful for file organization. I propose similar usefulness for extendables.

Code or steps to use

./extendables/User/profile.js:

const { Extendable } = require('klasa');

class MyExtendable extends Extendable {

    get extend() {
        // return whatever
    }

}

module.exports = MyExtendable;

A file that uses it:

msg.author.profile // etc.

Caveats

  • You wouldn't be able to specify multiple classes to apply the extendable to
    • You can still explicitly use the appliesTo arg
    • How often do users use multiple classes in appliesTo, anyway?
  • You could do something unintuitive, like have a file ./extendables/User/modLog.js, with appliesTo: ['Guild']
    • That's your problem, to be honest; you can already do unintuitive things
  • Unlike command categories, extendable appliesTo can be set explicitly with an option; this makes for an inconsistency in Klasa
  • For a class that one has a lot of extenders for, it probably makes more sense to make a class extending it and pass that to Discord.js directly, rather than using Klasa extendables

Bug: RichDisplays in DMs Destroy Logs

Describe the issue

Having a RichDisplay sent in a DM will cause havoc on your logs. The commands work perfectly. The rich display works perfectly. The pages change perfectly. It does everything that it should do but it keeps sending this error to your log for every reaction that clicked. So if a user clicks 2-3 times and you have thousands of users on a popular command it destroys logs.

There should be a way to catch/ignore this error somehow because as I said the command works perfectly. The users have no issues. But the developer logs are insanely spammed.

Uncaught Promise Error: 
DiscordAPIError: Cannot execute action on a DM channel
 at item.request.gen.end (node_modules/discord.js/src/rest/handlers/RequestHandler.js:79:65)
at then (node_modules/snekfetch/src/index.js:218:21)
 at <anonymous>
 at process._tickDomainCallback (internal/process/next_tick.js:228:7)

Code or steps to reproduce

1) Create a rich display command to run in a DM
2) Use reactions
3) Check logs

Expected an actual behaviour

Either a workaround or some sort of method to avoid this log is necessary. The only issue here is with the error log and not the RichDisplay or command. All i really need is a way to ignore this error from my console.

Further details

  • discord.js version: latest
  • node.js version: 9+
  • Klasa version: latest
  • I have modified core files.
  • I have tested the issue on latest master. Commit hash:

Bug: parameters handled correctly when using quotedStringSupport with custom usageDelim

When quotedStringSupport is set to true and a command uses a usageDelim that is not a space, commands with the repeator tag do not work correctly. (Tested with user type).

Expected Behaviour

Klasa would get all users and send an array of users.

Actual Behaviour

When I input one user, it works perfectly, but it fails with two or more.

Command input

> $test 383383927575937034, 242043489611808769
Error: person must be a mention or valid user id.
> $test "383383927575937034" "242043489611808769"
Error: person must be a mention or valid user id.
> $test "383383927575937034", "242043489611808769"
Error: person must be a mention or valid user id.

Code to reproduce

const { Command } = require('klasa');

module.exports = class extends Command {

	constructor(...args) {
		super(...args, { usage: '<person:user> [...]', usageDelim: ', ' });
	}

	run(msg, [...user]) {
		return msg.send(`Mentioned: ${user.map(us => us.tag).join(', ')}`);
	}

};

Extra details

When quotedStringSupport is set to false, it does parse the ids correctly.

Help command on iOS

Describe the issue

image

Code or steps to reproduce

Use the built-in help command on iOS

Expected an actual behavior* *Google is always right /s

image

Further details

  • discord.js version: 12.0.0-dev
  • node.js version: v9.8.0
  • Klasa version: 0.5.0-dev
  • I have modified core files.
  • I have tested the issue on latest master. Commit hash:

To fix: Add newline before starting the codeblock
Additional: Remove blank newline at end of codeblocks
image

Proposal: Move initial config out of the constructor

Describe the issue

Currently, we are using constructor to set up the config of a class.
Instead, we could use a method of the class. This will keep the code clean, simpler and more dynamic.

Code or steps to reproduce

class Parent {
  constructor(...args) {
    // Do something with it
    console.log(args)
  }
}

class Children extends Parent {
  constructor(...args) {
    super(...args, {
      command: "ping"
    })
  }
}

Expected an actual behaviour

class Children {
  constructor(...args) {
    let config;
    if (typeof this.config === "function") config = this.config();
    if (!config) throw Error("You forgot to set the config using the method config");
    
    // Do something with config or just make it available for the methods
    this._internalConfig = config;
  }
}

class TestChild extends Children {
  config() {
    return {"command": "ping"}
  }
}

Proposal: Inhibitor priority like in Komada

Describe the proposal

At the moment we have absolutely no control about the order the inhibitors are run in. And for some ideas there is the scenario needed to run one inhibitor before another and to stop the the whole process
(to not run the other inhibitors following)

Bug: RichDisplay Requiring 2 Reaction Taps To Change Page

Describe the issue

With the fix of #147 it led to a new issue where the reaction needs to be tapped twice. I believe it occurs because now there is no way to remove the reaction automatically so you have to a) remove b) add new reaction.

EDIT: Oops sorry I wasn't saying the fix caused it just revealed that it needs 2. Even before the fix this issue occurred because the bot couldn't remove the reactions so they still had to click twice. This fix simply revealed this issue more to me.

Code or steps to reproduce

1) Create a richdisplay to run in DM
2) run the command and go to page 2
3) try to go to page 3 but it wont
4) click again and it will go to page 3

Expected an actual behaviour

The RichDisplay when it lacks perms to remove reactions could work when the user removes a reaction to move to next page

Further details

  • discord.js version: latest
  • node.js version: 9+
  • Klasa version: latest
  • I have modified core files.
  • I have tested the issue on latest master. Commit hash:

Proposal: Better wildcard support in Cron

Describe the proposal

With the PR #156 we have implemented Cron, however, we wanted to have a fully functional Cron before pulishing it and implement the rest of features. Currently, we're missing five non-standard wildcards:

Edit: Added Done column to the wildcard table and a list of commits implementing the new wildcards.

Done Wildcard Description
- L 'L' stands for "last". When used in the day-of-week field, it allows you to specify constructs such as "the last Friday" ("5L") of a given month. In the day-of-month field, it specifies the last day of the month.
- W The 'W' character is allowed for the day-of-month field. This character is used to specify the weekday (Monday-Friday) nearest the given day. As an example, if you were to specify "15W" as the value for the day-of-month field, the meaning is: "the nearest weekday to the 15th of the month." So, if the 15th is a Saturday, the trigger fires on Friday the 14th. If the 15th is a Sunday, the trigger fires on Monday the 16th. If the 15th is a Tuesday, then it fires on Tuesday the 15th. However, if you specify "1W" as the value for day-of-month, and the 1st is a Saturday, the trigger fires on Monday the 3rd, as it does not 'jump' over the boundary of a month's days. The 'W' character can be specified only when the day-of-month is a single day, not a range or list of days.
? In some implementations, used instead of '*' for leaving either day-of-month or day-of-week blank. Other cron implementations substitute "?" with the start-up time of the cron daemon, so that ? ? * * * * would be updated to 25 8 * * * * if cron started-up on 8:25am, and would run at this time every day until restarted again.
- # '#' is allowed for the day-of-week field, and must be followed by a number between one and five. It allows you to specify constructs such as "the second Friday" of a given month. For example, entering "5#3" in the day-of-week field corresponds to the third Friday of every month.
H 'H' is used in the Jenkins continuous integration system to indicate that a "hashed" value is substituted. Thus instead of '20 * * * *' which means at 20 minutes after the hour every hour, 'H * * * *' indicates that the task is performed every hour at an unspecified but invariant time. This allows spreading out tasks over time.

From the Wikipedia page.

We also support nonstandard predefined scheduling definitions, however, @yearly is supported where @annually isn't. (✅).

Implementation

  • [4b4a42ad0f] Fixed the wildcard ?. (bdistin)
  • [692e485d2b] Implemented the wildcards ?, H, and the scheduling definition @annually. (bdistin)

Further details

Proposal: Better command ratelimits

Describe the proposal

The implementation of Command#cooldown is very effective, and it got enhanced thanks to Command#bucket allowed developers to have a better control of them without annoyingly set ratelimits at first command usage and disturb the user.

However, the underlying system feels incomplete and not very performant.

  • It uses a timeout for every single cooldown, this is separated in multiple commands, so both RAM and CPU usage seems to be affected by this. In practice, the excessive amount of timeouts seems to make other shift even a bit. This could be fixed with a cooldown sweeper using an interval, similar to Schedule's system.

  • It's not very effective: if a user spams a command, they should be notified only once, however, Klasa will reply as many times as it can. Some developers (me, included) use ratelimits to protect the bot from, not only heavy processing or limit the usage of commands, but also to protect the bot against breaking Discord ratelimits. That is, due to the lack of silent ratelimits.


Finally, there's an extreme side case that has been affecting my bot today: it's cool to put the ratelimits after a successful command run, however, there are commands (such the ones that send files or generates images) that take a while longer. These commands take more to resolve, therefore, they also take longer to fire the finalizers that put the user in cooldown. For example, I have a command that takes ~1 second to process an image and send it to Discord, the command has a cooldown of 30 seconds with a bucket of 1. A user sends 5 messages within that second.

Expected behavior: Run one, ratelimit the second, ignore the other three (with this proposal).
Actual behavior: As cooldowns aren't applied until the first successful command run, the bot does run all 5 commands.

Implementation

  • Cooldown Sweeper: Not implemented yet.
  • Silent Cooldown: Not implemented yet.

Cannot set property ... of null (SG)

Describe the issue

Error when trying to update a SG config of type 'any' with an object.

TypeError: Cannot set property 'test' of null

Code or steps to reproduce

  1. Get a raw app.js, only changing the token value - or skip to Step 4 if you have an unmodified bot running the latest klasa/d.js master that you can test on.

  2. Install Klasa, Discord Master:

    • npm i -S discordjs/discord.js
    • npm install dirigeants/klasa
    • npm install
  3. Run the bot.

  4. Add a key to your schema of type any:

+eval this.client.gateways.users.schema.add("test", { type: "any" })
  1. Update someones configs, in the test key, with an Object value.
+eval msg.author.configs.update("test", { test: 'test' });
  1. Reset the Object value in the test key of the users config.
+eval msg.author.configs.reset("test");
  1. Update the users config again, in the test key, with an Object value.
+eval msg.author.configs.update("test", { test: 'test' });
  1. Observe error: TypeError: Cannot set property 'test' of null. If the error doesn't appear, try rebooting the bot and trying it again.

Expected an actual behaviour

The test key in the users' configs should be updated with the Object value.

Further details

  • discord.js version: v12.0.0-dev
  • node.js version: v9.3.0
  • Klasa version: v0.5.0-dev
  • I have modified core files.
  • I have tested the issue on latest master. Commit hash:

Proposal: Arguments enhancement.

Describe the issue

We can agree that usage strings are very cool, very easy to use, very clean and readable, compared to other systems implemented in other frameworks with are, for example, an array of objects that lately face the issue of union type, something easy to write thanks to the usage string. However, as easy as it is, the usage string has one weakness that we can't address in the current way, for that, I have multiple proposals.


UsagePrompt

This is @MrJacz's proposal, an array typeof Array<string | (msg: KlasaMessage) => string. This is the easiest way to address this issue as it's another property for CommandOptions: usagePrompt. It's usage would come to be something similar to:

{
    usage: '<battletag:string> [bronze|silver|gold|platinum]',
    usageDelim: ' ',
    usagePrompt: [
        'Give me a battletag formatted as username#0000',
        'Give me a rank name, can be bronze, silver, gold or platinum, pick the one that is next to your rank.'
    ]
}

However, it's lineal and to do so you may need to pass empty values or undefined in the middle of the array, to address that, it's possible to have a class do that:

{
    usage: '<battletag:string> [bronze|silver|gold|platinum]',
    usageDelim: ' ',
    usagePrompt: new UsagePrompt()
        .addPrompt(1,
            'Give me a rank name, can be bronze, silver, gold or platinum, pick the one that is next to your rank.')
}

Where 0, being <battletag:string>, would use the default message (battletag is a required argument).


However, it may be confusing, may it start with zero? Or maybe with one? To address this issue, we could make CommandOptions.usage accept more types: not just string.

ArgumentUsage

{
    usage: new ArgumentUsage()
        .addParameter('battletag', /(\w{4,12})#(\d{4,5})/, true,
            'Give me a valid BattleTag, should be formatted like someuser#0000')
        .addParameter('rank', 'bronze|silver|gold|platinum', false,
            'Give me a rank name, can be bronze, silver, gold or platinum, pick the one that is next to your rank.'),
    usageDelim: ' '
}

Where ArgumentUsage is a class that compiles directly to ParsedUsage and has a .toString() method to compile to usageString (used in the help command, for example). The reason this would compile to ParseUsage is so it's able to add the new properties to the possibles: promptMessage being either a string or callback (msg: KlasaMessage) => string.

The Argument#addParameter option is very powerful as it doesn't only add one more feature to Usage, which is prompt, but it also adds two more (nice) features: the possibility to have raw RegExp to use as regexp type (I'll be honest, I haven't figured the RegExp type since it got released, it's very complicated inside usageString, if this gets merged, the usage of the RegExp type in Klasa will be significantly easier) or even a custom type. Of course, this part of the concept can change, and name would be... perhaps custom or allow a fifth parameter which is parameter name for usageString. This can be reviewed later.

Furthermore, stringifying a RegExp for usageString is relatively easy, RegExp#toString() does that.

This method would also support strings as legacy and would allow union type. Of course, this could use the current usageString parser, covering the downsides of the systems that are not based in quotedString.

The design of this method is inspired on PermissionLevels to keep the design of the framework and its core pieces.

EDIT: Stringifying an ArgumentUsage instance would be as easy as mapping all the entries and write argName:typeName/typeParam then wrap with < and > or [ and ] depending on whether the value of the second parameter is true or false.

class ArgumentUsage {

    public constructor();
    private _entries: object[];

    public addParameter(
        argName: string, 
        type: string | RegExp | (msg: KlasaMessage, arg: string) => string,
        required: boolean,
        promptMessage?: string | (msg: KlasaMessage) => string,
        typeName?: string): this;

    public toJSON(): object;
    public toString(): string;

}

EDIT 2: ArgumentUsage is not meant to replace the former usageString, but to complement as a more advanced tool that opens the gates for more creativity, implementing better debugging (IntelliSense, separation of the "parts" of each Tag, custom types, better RegExp readability...) and the possibilities to reach where usageString can't reach while also using the parser for the aforementioned to cover the issues this kind of system has in other frameworks (lack of union type as an example).

This is more than just an enhanced usage, this allows better debugging, better internationalization, custom messages/prompts (feature highly requested over almost half a year) and improves user friendly-ness towards users.

Implementation

None.

Further details

Proposal: Better SchemaPiece options

Describe the proposal

Since SGv1, in the PR #255 from Komada, we had the first implementation of SchemaPiece being able to store more than a single value of the same type (instead of being type array, from the former configuration system).

However, this system is extremely old and should be renamed and refactored into something much better, in this proposal, I'll use SchemaPiece#multiValue as a placeholder for a better name.

What does SchemaPiece#multiValue do compared to SchemaPiece#array? The current name limits the options, the values may be contained inside an array or not, but, what if I want to use Set or Map? The current system does not allow it, but multiValue will.

Implementation

There are multiple ways to achieve this, but I'll present two in this proposal:

ValueController

This is more versatile, it allows custom types and moves some of the heavy work from SG to them, it also allows users to implement their own ValueController, for example, one being Collection extending Map and so on. Compatibility with string for simplicity in SchemaFolderAddOptions is accepted with a later resolve.

Said ValueController would implement basic methods such as create, clone, add, remove and modify and they could be stored in GatewayDriver together with the available key types.


Internal Resolving

This is less customizable and more hardcoded, plus makes SettingGateway's internals much heavier. These methods would be integrated in a different file (similar to a util) for later usage.


In both options, you'll be able to do

SchemaFolder#add('tags', { type: 'string', multiValue: 'Map' });

And the new values will be stored in the Map. However, some of the multiValue may not be able to be directly configurable, so they'll have the same behavior as type: 'any': sets SchemaPiece#configurable to false.

This proposal is not merging on #179 but in a later one.

Proposal: Add an array of wanted ids to be requested in Provider#getAll

Describe the proposal

Currently Provider#getAll wants just the table, and expects to return all the data. That is horrible, because that means you could potentially be fetching thousands of documents for no apparent reason. (not to mention in

async _download() {
const entries = await this.provider.getAll(this.type);
for (const entry of entries) {
const cache = this.cache.get(entry);
if (cache) {
if (!cache._existsInDB) cache._existsInDB = true;
cache._patch(entry);
} else {
const configs = new this.Configuration(this, entry);
configs._existsInDB = true;
this.cache.set(entry.id, configs);
}
}
}
it fetches all data so you also have never used data cached in your shards)

This proposal suggests adding an optional array of ids to the getAll functions, where each provider has to handle it manually (most databases have ways of doing this. Mongo has $in, most of sql seems to have select item from table where item.id in (values, here), rethink can do filtering, etc.)

Example Code

async getAll(table, filter = undefined) {
    if (util.isArray(filter)) {
        // Fetch data based on the filter, where each item in filter is the id
        // for instance, assuming we have sql
        return this.run(`SELECT * FROM ${table} AS g WHERE g.id IN (${filter.join(",")})`)
    }
    // Fetch all data like normal
}

Expected and actual behaviour

This should return all data if no array is provided, or filtered data otherwise. This should NOT have to fetch all data and return the correct one, but should rather integrate with the database's syntax and fetch exactly whats needed at once.

Further details

  • discord.js version: not relevant
  • node.js version: not relevant
  • Klasa version: 0.5.0-dev
  • I have modified core files.
  • I have tested the issue on latest master. Commit hash:

Typo in the core command disable.js

When you issue the command to disable the message event. It should not let you, but yet it does.
It's simple to fix the problem. All that needs to be done is change Message to message. (See the code below)

// peice.name === 'Message' should actually be piece.name === 'message'
async run(msg, [piece]) {
		if ((piece.type === 'event' && piece.name === 'Message') || (piece.type === 'monitor' && piece.name === 'commandHandler')) {
			return msg.sendMessage(msg.language.get('COMMAND_DISABLE_WARN'));
		}
		piece.disable();
		return msg.sendCode('diff', msg.language.get('COMMAND_DISABLE', piece.type, piece.name));
	}

Expected and actual behaviour

It is expected to prevent you from disabling the message event handler.
It's actual behavior, disables the message event handler and prevents you from issuing further commands.

cmdDeletion doesn't work anymore after the cmdEditing rewrite

Describe the issue

as the title already says the cmdDeletion doesn't work anymore after the cmdEditing rewrite.

Code or steps to reproduce

const { Client } = require('klasa');

new Client({
    prefix: '+',
    cmdDeleting: true,
    readyMessage: (client) => `Successfully initialized. Ready to serve ${client.guilds.size} guilds.`
}).login('your-bot-token');

Expected an actual behaviour

Delete the message if invoke message is deleted

Further details

  • discord.js version: newest master (discordjs/discord.js@a5e8f05)
  • node.js version: 9.10.1
  • Klasa version: newest master (7de01e1)
  • I have modified core files.
  • I have tested the issue on latest master. Commit hash: 7de01e1

Proposal: "spamProtection"property for inhibitors

Describe the proposal

I think this term is very misleading for a property that is only there to prevent an inhibitor to be run for the help command. If we want it configurable for inhibitors to only be run in certain scenarios, this should be more configurable.

Bug in the blacklist command

Describe the issue

Code or steps to reproduce

Usage with prefix !

!blacklist @stitch#9441

Expected an actual behaviour

Blacklists me. Instead, it says "guildID must be between 17 and 19 characters.

Further details

  • discord.js version: latest master
  • node.js version: 10.0.0
  • Klasa version: latest master
  • I have modified core files.
  • I have tested the issue on latest master. Commit hash:

Suggestion: Better usage of moment.js

For a long time, we have depended of the moment package, however, its i18n support is not used, as well as it is a bit hard to use, check the reference here. We could do two things:

  • 1.- Remove moment as a dependency and make our own one, this would be very similar to what we did with chalk before (thanks to Faith), and we could get rid of many weird issues when using moment-duration-format. Then, our implementation could be more efficient with the latest V8 changes and easier to use.

  • 2.- Modify our usage of moment so it's multilanguage. (It is used in the stats command to show how long has a bot been running for).

    `• Uptime :: ${moment(Date.now() - (process.uptime() * 1000)).toNow(true)}`,

An in-range update of typescript is breaking the build 🚨

Version 2.5.3 of typescript just got published.

Branch Build failing 🚨
Dependency typescript
Current Version 2.5.2
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

As typescript is “only” a devDependency of this project it might not break production or downstream projects, but “only” your build or test tools – preventing new deploys or publishes.

I recommend you give this issue a high priority. I’m sure you can resolve this 💪

Status Details
  • continuous-integration/travis-ci/push The Travis CI build could not complete due to an error Details

Release Notes TypeScript 2.5.3

This release include a set of bug fixes reported against TypeScript 2.5.2. For the complete list of fixed issues, check out the fixed issues query for TypeScript 2.5.3.

Download:

Commits

The new version differs by 51 commits.

  • 94b4f8b Update LKG
  • aa40be6 Merge pull request #18673 from RyanCavanaugh/port18603
  • 6281b05 Report external files in initial case
  • 5538770 Look at correct 'package.json' location for a scoped package (#18580) (#18651)
  • acfd670 Merge pull request #18617 from amcasey/NoModifiers25
  • 9630c46 JavaScript: handle lack of modifiers on extracted method
  • 7b5247f Merge pull request #18605 from RyanCavanaugh/portExternalFilesFixes
  • 6ed9bad Port plugin fixes from master
  • e9a9d2c Merge pull request #18518 from amcasey/ExtractMethodFixes25
  • 27bede8 Stop requiring that the full range of a declaration fall within the
  • f0b7843 Merge pull request #18508 from amcasey/ExtractSingleToken
  • 063e8a7 Merge pull request #18427 from amcasey/GH17869
  • fbb6cd5 Merge pull request #18448 from amcasey/NestedReturn
  • a667b04 Merge pull request #18423 from amcasey/GH18188
  • 334125e Merge pull request #18343 from amcasey/InsertionPosition

There are 51 commits in total.

See the full diff

Not sure how things should work exactly?

There is a collection of frequently asked questions and of course you may always ask my humans.


Your Greenkeeper Bot 🌴

[TYPO] Mistake in function msg.hasAtleastPermissionLevel(#)

Apparently, on the docs, it shows this for checking the Permission level of a msg.

msg.hasAtleastPermissionLevel(#)

However, when testing this it ends up returning:
0|app | [2017-10-24 19:12:40] TypeError: msg.hasAtleastPermissionLevel is not a function 0|app | [2017-10-24 19:12:40] at module.exports.run (/home/jordan/Sistine/commands/Currency/balance.js:38:31) 0|app | [2017-10-24 19:12:40] at msg.validateArgs.then (/home/jordan/Sistine/monitors/commandHandler.js:66:19) 0|app | [2017-10-24 19:12:40] at <anonymous>

The function ends up working if you capitalize the l in Atleast to AtLeast.
https://dancing.while-at.work/3f4e0f.png

[1.0.0 Roadmap] Remove all SQL state from the library (and schema).

The library should not care anything about what the provider is using in the background. This also allows for each sql provider to be more customized to that individual database, rather than trying to find a set of sql syntax/types common to all sql databases. As well as reduction of core code (bloat) and finally massive simplification of SettingGateway.

Potentially add a SQL QueryBuilder Util with overridable defaults, to aid in reduction of duplicate code/making SQL Providers more maintainable.

Suggestion: RegExp prefix's

A way to be able to have custom Prefix with regex's aka this.client.config.prefix could be new RegExp(/!/g) for example

Scheduled task not behaving as expected

Describe the issue

I got multiple recurring tasks that should ran every minute but what happens is that the first task runs then the second ones run in the second minute and in the third minute the third tasks runs, and a loop starts.

Code or steps to reproduce

Make multiple recurring tasks (mine hapened with the same task) with the cron "* * * * *" (that means that they should run every minute of every hour of every day, etc), after that check how the multiple recurring tasks are executing, for example if you want to do a simple test you could make a task that does console.log("test"), and that should appear n times (n being the amount of recurring tasks you made) in the console but it doesnt.

Expected an actual behaviour

What should happen is that your console should be filled of "test" but it is not because only one scheduledTask was ran.

Further details

  • discord.js version: 12.0.0dev
  • node.js version: 8.11.1
  • Klasa version: 0.5.0dev
  • I have modified core files.
  • I have tested the issue on latest master. Commit hash: c6be589

Proposal Design: QueryBuilder

Describe the proposal

The PR #228 went into stale due to the lack of an objective design and lack of a technical specification for QueryBuilder. This issue will remain opened until the design for QueryBuilder gets fully written, specified and merged into the master branch.

I'm opening this issue as QueryBuilder is part of the v1.0.0 RoadMap and therefore, its design should start taking priority so it can be written, tested and merged before discord.js 12 does, that way we can land the long-awaited Klasa 1.0.0 with discord.js 12 release.

The current (and last written) version of QueryBuilder looked like this:

// Create a QueryBuilder for PostgreSQL
this.qb = new QueryBuilder(this.client, {
	// Declare the boolean type, with the datatype name as "BOOL"
	// and defaults false and true
	BOOLEAN: { name: 'BOOL', default: [false, true] },
	// Declare the float type, defaults to 0
	FLOAT: { name: 'DOUBLE PRECISION', default: 0 },
	// Declare the integer type, defaults to 0
	INTEGER: { name: 'INTEGER', default: 0 },
	// Declare the text type, defaults to NULL
	TEXT: { name: 'TEXT' },
	// Declare the varchar type, defaults to NULL, the property of
	// size tells QB to use VARCHAR(MAX_LENGTH)
	VARCHAR: { name: 'VARCHAR', size: true }
}, {
	// When using arrays, PG converts INTEGER to INTEGER[]. So we want
	// to append '[]' at the end of the type
	arrayWrap: (type) => `${type}[]`
});

However, this design has not been approved by the team. I would also like to open this to everyone who wants to contribute in the design of QueryBuilder (perhaps we can take a look to Sequelize and Knex, and get the best of them for some aspects?).

Suggestion: awaitMessage Tool

There are some really good stuff on Klasa that use reactions and paginations and make life a lot more easier and amazing with stuff like RichDisplay and RichMenu.

I was wondering if there was a chance of incorporating something similar for awaitMessages. I use this as an application of sort and was hoping for an awesome way to do this.

it would require parameters like:
an object that shows how many different questions you need to be answered, time for each question, type of response like options which could use reactions etc

Let me know if I am not clear on the suggestion and would like more details I will be happy to elaborate.

Help command breaks with too many commands in a category

Describe the issue

If your category has over a certain amount of commands (54 in my case) the default help commands breaks due to not correctly splitting the codeblocks (the .send() catch fires with a wrong message)

Code or steps to reproduce

  1. create a category with a lot of commands
  2. try to use the help command

Expected an actual behaviour

show help command correctly

Further details

An in-range update of eslint is breaking the build 🚨

Version 4.10.0 of eslint was just published.

Branch Build failing 🚨
Dependency eslint
Current Version 4.9.0
Type devDependency

This version is covered by your current version range and after updating it in your project the build failed.

eslint is a devDependency of this project. It might not break your production code or affect downstream projects, but probably breaks your build or test tools, which may prevent deploying or publishing.

Status Details
  • continuous-integration/travis-ci/push The Travis CI build failed Details

Release Notes v4.10.0
  • bb6e60a Fix: Improve the doc for no-restricted-modules rule (fixes #9437) (#9495) (vibss2397)
  • c529de9 Docs: Amend rule document to correct and complete it (refs #6251). (#9498) (Jonathan Pool)
  • f9c6673 Chore: Add tests to cover array and object values and leading commas. (#9502) (Jonathan Pool)
  • 9169258 Chore: remove npm run check-commit script (#9513) (Teddy Katz)
  • 7d390b2 Docs: Revise contributor documentation on issue labels. (#9469) (Jonathan Pool)
  • d80b9d0 Fix: no-var don't fix globals (fixes #9520) (#9525) (Toru Nagashima)
  • b8aa071 Fix: allow linting the empty string from stdin (fixes #9515) (#9517) (Teddy Katz)
  • 350a72c Chore: regex.test => string.startsWith (#9518) (薛定谔的猫)
  • de0bef4 Chore: remove obsolete eslintbot templates (#9512) (Teddy Katz)
  • 720b6d5 Docs: Update ISSUE_TEMPLATE.md (#9504) (薛定谔的猫)
  • 2fa64b7 Fix: should not convert non-consecutive line comments to a single blo… (#9475) (薛定谔的猫)
  • 9725146 Fix: multiline-comment-style fix produces invalid code (fixes #9461). (#9463) (薛定谔的猫)
  • b12cff8 Fix: Expected order of jsdoc tags (fixes #9412) (#9451) (Orlando Wenzinger)
  • f054ab5 Docs: add .md to link (for github users) (#9501) (薛定谔的猫)
  • 5ed9cfc Docs: Correct violations of “Variable Declarations” in Code Conventions (#9447) (Jonathan Pool)
  • 3171097 Docs: Clears confusion on usage of global and local plugins.(#9492) (Vasili Sviridov)
  • 3204773 Chore: enable max-len. (#9414) (薛定谔的猫)
  • 0f71fef Docs: Unquote booleans in lines-between-class-members docs (#9497) (Brandon Mills)
  • b3d7532 Docs: use consistent terminology & fix link etc. (#9490) (薛定谔的猫)
  • 87db8ae Docs: Fix broken links (#9488) (gpiress)
  • 51bdb2f Docs: Incorrect link to related rule (#9477) (Gavin King)
  • 1a962e8 Docs: Add FAQ for when ESLint cannot find plugin (#9467) (Kevin Partington)
  • 8768b2d Fix: multiline-comment-style autofixer added trailing space (#9454) (Teddy Katz)
  • e830aa1 Fix: multiline-comment-style reports block comments followed by code (#9450) (Teddy Katz)
  • b12e5fe Docs: Repair broken links and add migration links. (#9473) (Jonathan Pool)
  • eca01ed Docs: Add missing info about special status of home-dir config files. (#9472) (Jonathan Pool)
  • eb8cfb1 Fix: change err report in constant condition (fixes #9398) (#9436) (Victor Hom)
  • da77eb4 Chore: Revise no-config-file test to prevent false failure. (#9443) (Jonathan Pool)
  • 47e5f6f Docs: ensure "good commit message" examples actually follow guidelines (#9466) (Teddy Katz)
  • ebb530d Update: Don't ignore comments (no-trailing-spaces) (#9416) (Chris van Marle)
  • 5012661 Build: fix npm run profile script (fixes #9397) (#9455) (Teddy Katz)
  • ecac0fd Docs: Remove blockBindings references (#9446) (Jan Pilzer)
  • 0b89865 Chore: ensure tests for internal rules get run (#9453) (Teddy Katz)
  • 052c504 Docs: suggest deleting branches after merging PRs (#9449) (Teddy Katz)
  • b31e55a Chore: move internal rules out of lib/ (#9448) (Teddy Katz)
  • a7521e3 Docs: improve examples for multiline-comment-style (#9440) (Teddy Katz)
Commits

The new version differs by 38 commits.

  • 9deb1b1 4.10.0
  • 6d19001 Build: changelog update for 4.10.0
  • bb6e60a Fix: Improve the doc for no-restricted-modules rule (fixes #9437) (#9495)
  • c529de9 Docs: Amend rule document to correct and complete it (refs #6251). (#9498)
  • f9c6673 Chore: Add tests to cover array and object values and leading commas. (#9502)
  • 9169258 Chore: remove npm run check-commit script (#9513)
  • 7d390b2 Docs: Revise contributor documentation on issue labels. (#9469)
  • d80b9d0 Fix: no-var don't fix globals (fixes #9520) (#9525)
  • b8aa071 Fix: allow linting the empty string from stdin (fixes #9515) (#9517)
  • 350a72c Chore: regex.test => string.startsWith (#9518)
  • de0bef4 Chore: remove obsolete eslintbot templates (#9512)
  • 720b6d5 Docs: Update ISSUE_TEMPLATE.md (#9504)
  • 2fa64b7 Fix: should not convert non-consecutive line comments to a single blo… (#9475)
  • 9725146 Fix: multiline-comment-style fix produces invalid code (fixes #9461). (#9463)
  • b12cff8 Fix: Expected order of jsdoc tags (fixes #9412) (#9451)

There are 38 commits in total.

See the full diff

FAQ and help

There is a collection of frequently asked questions. If those don’t help, you can always ask the humans behind Greenkeeper.


Your Greenkeeper Bot 🌴

Easy way to disable individual core commands

Describe your proposal

I want an easy way to disable individual core commands.

Usecases for your proposal

I don't want to have the user-conf command in my bot. At least not in the near future. There is no nice way to get rid of it, without getting rid of all the other core commands.

Expected and actual behaviour

Currently I'd need to transfer the command file, then set enabled: false, then maybe move it into a folder called 'Disabled' or something. That is quite annoying, especially if I wanna make the bot open source. I don't want a random folder with some commands that shouldn't be touched.

I want a way to be able to persistently disable individual core commands globally, that'd work with OSS. You could put it into the Client initialization, maybe?

I really hope this is added, as this issue is really annoying me.
Thanks for reading.

Unmark pieces' typings as abstract.

Describe the issue

Almost all of the pieces' typings mark certain methods as 'abstract'.
The methods are normally optional, but the 'abstract' marking forces you to implement them.

Code or steps to reproduce

import { Command } from 'klasa';
import { Client } from '../../structures/Client';

// [ts] Non-abstract class 'default' does not implement inherited abstract member 'disable' from class 'Command'.
export default class extends Command {

	constructor(client: Client, dir: string, file: string[]) {
		super(client, dir, file, {
			aliases: ['details', 'what'],
			description: 'Provides some information about this bot.'
		});
	}

	async run(msg) {
		return msg.sendMessage(msg.language.get('COMMAND_INFO'));
	}

};

Expected an actual behavior

No errors; typescripts allows the class.

Further details

  • discord.js version: 11.3.2
  • node.js version: 10.1.0
  • Klasa version: 0.4.0
  • I have modified core files.
  • I have tested the issue on latest master. Commit hash:

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.