eritbh / yuuko Goto Github PK
View Code? Open in Web Editor NEW๐ฐ No-frills Discord command framework for Eris
Home Page: http://eritbh.me/yuuko
License: MIT License
๐ฐ No-frills Discord command framework for Eris
Home Page: http://eritbh.me/yuuko
License: MIT License
how have i not done that yet
Store results in Client#app
and possibly emit a new event when this is populated?
Sometimes a user can make a silly typo and to prevent them from having to remake the entire command again, having the ability to reprocess a message on messageUpdate
would be really cool.
From a developer perspective, this becomes really useful for the debug
command as you can easily, edit the message incase you want to go 1 layer deeper into the object.
This will make everything cleaner and eliminate a bunch of extra garbage
~roll 10
= ~roll 1d10
)~roll
= ~roll 1d6
)Relevant: Should rewrite the dice roll command to use d20.js which makes the first one much easier. It also supports roll modifiers which would get rid of a thing I have on my whiteboard.
Currently, custom messageCreate
listeners can't get too much information about run commands when calling client.processCommand
. It only returns a true
or false
value that indicates whether a command was run; it doesn't indicate what command was run, and it also treats a command's failing permission checks identically to a message not containing a command at all. The only way around this at the moment is to copy-paste the implementation of processCommand
into the custom handler, which isn't well documented and isn't easy to work with.
Ideally, processCommand
would return some object describing the execution that's occurred, including the command that was specified (if any), the arguments passed to it (*), and whether or not it was executed (and if not, maybe the permission check that caused the command not to run?). This would be a breaking change.
(* This might cause confusion paired with #25/#68, since the method I'm going with for argument parsing is to do the parsing within the command process rather than before the command is executed. This might result in confusing behavior, and given command arguments can basically be obtained by msg.content.split(' ').slice(1)
(as long as your prefix doesn't have spaces), I'm not super convinced it would be worth it to provide the used arguments outside the actual command process.)
Client option or something else that lets you specify custom behavior for when the prefix is used but a command isn't matched.
this is dumb just do it, everything is outdated and its ur fault
TODOs:
Putting it here, so it could be useful to remember.
Making the client.commands
as a map, this can be really good when getting a command by name for example, so instead of doing:
const command = client.commands.find(cmd => cmd.names[0].toLowerCase() === "commandname");
you can just do:
const command = client.commands.get("commandname");
Being able to require('yuuko/commands/help')
to get a reliable default help command would make things much easier for newcomers.
This will also involve restructuring things slightly so the compiled JS files live in the root of the project. That way you won't need /dist
in the require path or whatever. Not a huge deal but it's something.
should default to true because ignoring bots is good
Let the user know which file couldn't be loaded when there's an issue loading something (when it exports the wrong thing or doesn't export anything).
needs investigation, ts node might not work with require.cache
the same way as node does. not sure how that will work exactly, hopefully it isn't literally impossible
When you organize commands inside folders, they no longer load up. The bot does not register anything that is nested inside the commands folder. Ideally, this should go as many folders as nested until it loads all the files.
Needs to be flexible - possibly allow for storing configuration data on multiple databases.
Things we definitely want to store here for each guild:
config
command to manage optionsArgument types with options that influence how they're parsed.
name#discrim
2d 3h 15m
parsing for timesAlso how do I make this extensible so others can define their own argument types?
ClientOAuthApplication
was deprecated in #56, which updated it to be a direct alias of the Eris type OAuthApplicationInfo
. Yuuko's ClientOAuthApplication
type was initially introduced before Eris included typings for OAuth application details, but it is now unnecessary; the Eris type can be swapped directly into consumer code.
The ClientOAuthApplication
type will be removed in the 3.0.0 release (#94).
The Client
methods addCommandDir
, addCommandFile
, and reloadCommands
were all deprecated in #29, when the EventListener
class was added. These functions now serve only as aliases for addDir
, addFile
, and reloadFiles
respectively, which means that despite their names, they are not actually limited to working on commands, but impact both commands and event listeners loaded from files. These methods can be directly replaced in consumer code.
addCommandDir
, addCommandFile
, and reloadCommands
will be removed in the 3.0.0 release (#94).
I still need more time to evaluate whether a caught-require strategy and no declared peer dependency is a good way to go for Typescript projects, but given so much Eris development is happening on branches and I don't trust npm's semver resolver, we should switch to a version specifier of *
or >=0.15.0
for better compatibility.
Related to #77
Allow commands to set permissions that are required to execute the command. This could be done by a list of flags or a function which returns true or false based on the message that contains the command.
Maybe allow both, but it just makes more sense like that to me.
I've started messing around with the structures for application commands and it seems pretty viable to integrate them into Yuuko, though I'm not exactly sure how much of the existing Command
structure they can share if any. Here's my initial notes.
Key differences and some thoughts on how we could unify the two structures:
createMessage
exist on both structures in Eris, which helps, but ultimately there's no working around this differenceSo essentially I think what I want is a new Command
-like class that can handle app commands as well as traditional commands, more or less providing a compatibility layer between application commands and text-based commands.
Something absolutely necessary for supporting application commands: When commands are registered to the client, the client is responsible for verifying that the commands exist in the right place on the server and updating things if not. Consumers shouldn't have to worry about posting to the API to update their commands when changes are made, that's the library's job.
Probably an async delay somewhere
Thought I had an issue for this already, guess not. Files loaded via addCommandFile
/addFile
should be able to export multiple commands or event listeners for registration.
Easiest way to go would probably be to support default exports being arrays; named exports are inconsistent between JS and TS and will make things a pain, but can be investigated later. Ultimately though I don't think translating named exports is a great idea since the actual names are unused by Yuuko.
Reimplement the existing command with http
/https
builtin modules, having a peer dep for this is annoying.
A cool thing could actually be to make
globalCommandRequirements
a client option instead of a property to assign later as the code will look a little bit cleaner
Making it look like something like:
const client = new Client({
otheroptions: 'bla',
globalCommandRequirements: {
dmOnly: false,
guildOnly: true
}
})
Adding help to a command is not great in Typescript right now.
const command = new Command(...);
(command as Command & {help: any}).help = {...};
export default command;
It would be nice if the default help command exported a subclass that could be used to create a command with help preattached.
class CommandWithHelp extends Command {
constructor (name, help, process, requirements) {
super(name, help, requirements);
this.help = help;
}
}
Yarn has started being more annoying than plain npm, let's just switch back to using npm as our package manager
Let commands have other commands in them. e.g. ~tag tagname
!= ~tag create tagname
etc.
Some concerns:
Command
instances, or just plain objects passed to the constructor? Or should subcommands just be done with a space in the name or something like that?process
should be optional and should print a list of subcommands by default I think.TODOs:
I have an idea for adding generic "hooks" to the bot that can run code when certain things happen (like events) and influence the execution flow by returning values (not like events). This needs research, but the idea is to have an event-like system that doesn't just emit when things happen, but also has the capability of asking the library consumer for information when it needs it.
Areas where this would be useful:
handleMessage
method (which is currently run from inside messageCreate
event) that lets you return a specific value if you don't want to execute commands from the created message. Or something like that.Things to think about:
The Client#setGlobalRequirements
method and the ignoreGlobalRequirements
client option were both deprecated in #75, with the addition of the globalCommandRequirements
client option.
Uses of Client#setGlobalRequirements
can be replaced with usage of the globalCommandRequirements
option like so:
// old
import {Client} from 'yuuko';
const bot = new Client({
...
});
bot.setGlobalRequirements(yourGlobalRequirements);
// new
import {Client} from 'yuuko';
const bot = new Client({
globalCommandRequirements: yourGlobalRequirements,
...
});
Uses of the ignoreGlobalRequirements
option can be replaced with conditionally setting globalCommandRequirements
, like so:
// old
import {Client} from 'yuuko';
const bot = new Client({
globalCommandRequirements: yourGlobalRequirements,
ignoreGlobalRequirements: process.env.NODE_ENV !== 'production',
...
});
// new
import {Client} from 'yuuko';
const bot = new Client({
globalCommandRequirements: process.env.NODE_ENV !== 'production' ? {} : yourGlobalRequirements,
...
});
Client#setGlobalRequirements
and the ignoreGlobalRequirements
client option will be removed in the 3.0.0 release (#94).
Couple reports of Client#reloadFiles()
not reloading properly, making an issue now because I keep forgetting to look into it
For function colors (rgb
, hsl
, hsv
):
hsl
or hsv
, percent signs are optionalhsl
, else assume rgb
For hex colors:
000000
--> #000000
(3380f27)#0
--> #000000
#01
--> #010101
Blocked on #1
Makes docs messy, re-exports make it unclear which package provides what, and one more require('eris')
/import 'eris'
isn't the end of the world for anyone
Is this version of Yuuko compatible with the new Discord API and the new dev version of Eris?
const {Plugin, Command} = require('yuuko')
module.exports = new Plugin('pluginName', {
init (client) {},
listeners: {
messageCreate (client, msg) {
console.log(msg.content)
}
},
commands: [
new Command('mycommand', function (msg) {
msg.channel.createMessage('test')
})
]
})
idfk what im doing with this lol
Instead of
export default new Command('ping', msg => {
// this could be long...
}, {
guildOnly: true,
});
we should support putting options at the beginning before the potentially long function body:
export default new Command('ping', {
guildOnly: true,
}, msg => {
// this could be long...
});
Same goes for EventListener
- especially important for this one since the once
option changes the meaning of the listener body significantly.
Will require deprecation for the old form - both should be supported until v3. Runtime checks will need to be present past v3 to support the options being optional but coming before another required parameter.
shower thought: instead of
new EventListener('ready', /* ... */, {once: true})
it would be trivial to allow
new EventListener('ready:once', /* ... */);
Is this a good idea? I don't know of any other options we'd want to put on an event listener, so is the options object even necessary? I feel like allowing it via options is a cleaner way to do it, but requiring a full options object for a single property that will always be true
or not present seems kinda eh. But I also don't think I would want the :ready
method to be the only way to do it, because it's pretty different from how anything else handles one-time listeners.
As far as typings go it should be pretty easy I think - can make a new interface for the events that uses template literal string types for the additional keys I think
dbf2027 removed the glob dependency and replaced the directory search system with one that doesn't check for dots in filenames like glob did.
When using deprecated methods, e.g. client.addCommandFile
, emit a warning. The warning code should be somehow related to the issue that discusses the deprecation so migration paths are accessible, and the warning message should also contain a short description of how to resolve it.
^
Remove bot-specific commands from the repo. Some commands will stay as optional defaults under #18 (probably just remove them for now and add help, etc. back later after 1.0 is released).
Fixes #2 (made out of scope)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.