Skip to content

Commit 8b2f60b

Browse files
committed
docs, middlewares, typings, fixes
1 parent 0735a8f commit 8b2f60b

13 files changed

+1327
-467
lines changed

README.md

+29-258
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
# string-commands
22

3-
The command handler and argument parser for anything.
3+
The all powerful command handler for anything.
44

55
## Features
66

7+
- Easy to use
78
- Recursive folder importing
8-
- Configurable message stylings
9+
- Compatability with older commands
10+
- Configurable messages (no defaults)
911
- Command checks (requirements)
10-
- Custom Command Arguments Parser
11-
- Custom command run function arguments builder
12+
- Middlewares
13+
- Argument handling with custom argument support
1214

1315
## Examples
1416

@@ -30,269 +32,38 @@ And then import using
3032
import { CommandHandler } from "string-commands";
3133
```
3234

33-
### Creating a Command Handler
35+
### Documentation
3436

35-
You can pass an object of options into the CommandHandler.
37+
See these for docs:
3638

37-
```js
38-
let handler = new CommandHandler({
39-
// inputs must also begin with prefix
40-
// you can set this to an empty string
41-
prefix: "!",
42-
43-
// by default, log uses console
44-
// set to false to disable logging
45-
log: false,
46-
// or put in your own logger
47-
log: myLogger,
48-
49-
// you can also put the functions here to overwrite them,
50-
// instead of overriding them after initialization
51-
// note that these are still optional
52-
transformCommand: () => {},
53-
buildArguments: () => {},
54-
});
55-
```
56-
57-
### Writing Commands
58-
59-
Commands are just objects that must have two properties:
60-
61-
- `name` (string) The name of the command
62-
- `run` (function) The 'runner function'
63-
64-
**Example Command:**
65-
66-
```js
67-
let myCommand = {
68-
name: "ping",
69-
run: (ctx, args) => {
70-
console.log("Pong!");
71-
},
72-
};
73-
```
74-
75-
#### Runner Functions
76-
77-
By default, the arguments of the runner functions are as follows:
78-
79-
```js
80-
run: (ctx, args) => {};
81-
```
82-
83-
The arguments of the Runner Functions are defined using `CommandHandler#buildArguments`
84-
85-
You can change the order, remove, or add new params to the runner functions by overwriting `CommandHandler#buildArguments` like so:
86-
87-
```js
88-
handler.buildArguments = (b) => {
89-
return [b.args, b.ctx.username];
90-
};
91-
92-
// which would make you be able to define the runner function as:
93-
let run = (args, username) => {};
94-
```
95-
96-
### Registering Commands
97-
98-
There are two ways to register commands:
99-
100-
**1. using an object:**
101-
102-
```js
103-
handler.registerCommand(cmd);
104-
handler.registerCommand({ ... });
105-
```
106-
107-
**2. from a folder (recursively):**
108-
109-
```js
110-
// path is "./commands" by default
111-
handler.registerCommands();
112-
handler.registerCommands(path);
113-
handler.registerCommands("./src/cmds");
114-
```
115-
116-
#### Registering old commands
117-
118-
If your project has old commands from another command handler that has differient command objects, you can still import them.
119-
120-
You can set the `CommandHandler#transformCommand` to a helper function that would 'transform' the exported object into a valid command object.
121-
122-
**Example:**
123-
124-
```js
125-
let oldCommand = {
126-
help: {
127-
name: "ping",
128-
},
129-
execute: async () => {},
130-
};
131-
132-
handler.transformCommand = (obj) => {
133-
if (!obj.name) obj.name = obj.help.name;
134-
if (!obj.run) obj.run = obj.execute;
135-
return obj;
136-
};
137-
```
138-
139-
### Checks
140-
141-
Your commands can also have custom checks. Its recommended to make the checks once and reuse them for commands.
142-
143-
Command Checks are just the same as runner functions, but they must return an object with these props:
144-
145-
- `pass` (boolean) - set to true if check succeeded
146-
- `message` (string) - if it failed, the message explaining why
147-
148-
```js
149-
{
150-
checks: [
151-
(ctx, args) => {
152-
// Im an useless check! Gonna make it run!
153-
return { pass: true };
154-
},
155-
156-
(ctx, args) => {
157-
// just you wait until you hear that im after you
158-
return {
159-
pass: false,
160-
message: "Hardcoded Failiure",
161-
};
162-
},
163-
];
164-
}
165-
```
166-
167-
### ArgumentParser
168-
169-
The argument parser is a complex system that parses and validates given arguments for you. This means no more if-else checks for arguments in every command :D
170-
171-
Argument parser will look into `args` of your command objects.
172-
173-
**Examples:**
174-
175-
Arguments are also just objects. They must have a `type`, the rest are **parser options**
176-
177-
Arguments can have custom names using `name`
178-
179-
For example, in the code below, the `rest: true` field is a parser option
180-
181-
```js
182-
{
183-
name: "say",
184-
args: [{
185-
type: "text",
186-
name: "yourMessage",
187-
rest: true,
188-
}],
189-
run: () => {},
190-
}
191-
```
192-
193-
**String Resolving:**
194-
195-
You can also put strings instead of objects, but the side effect is that you cant define other parser options.
196-
197-
```js
198-
args: ["text"];
199-
200-
// a ":" can be used to give it a name
201-
args: ["yourMessage:text"];
202-
203-
// it can also be marked optional and required
204-
args: ["[text]", "<text>"];
205-
206-
// you can use three dots in the end to set `rest: true`
207-
args: ["text..."];
208-
209-
// you can also combine it like so:
210-
args: ["<words:text>..."];
211-
212-
// you can also also turn the whole array into a string
213-
args: "<user:text> <points:number> [comment:string]...";
214-
```
215-
216-
#### Special Parser Options
217-
218-
**`rest` (boolean)** - if set to true, consumes the rest of the input with it
219-
**`optional` (boolean)** - if set to true, this argument is considered optional
220-
**`name` (string)** - define the name of the argument
221-
222-
#### Native Parsers
223-
224-
##### ArgumentParser: text
225-
226-
Options:
227-
228-
- `min` (number) - Minimum characters
229-
- `max` (number) - Maximum characters
230-
231-
##### ArgumentParser: number
232-
233-
Options:
234-
235-
- `min` (number)
236-
- `max` (number)
237-
- `isInt` (boolean = false) - If the number should be a whole number/no decimals/integer
238-
239-
#### Writing Custom Argument Parsers
240-
241-
Arguments parsers are internally called **Usage Parser**s.
242-
243-
An usage parser is an object, like an argument, but with a `parse` function.
244-
245-
```js
246-
// usage parser: "that"
247-
{
248-
// underlying type
249-
type: "text",
250-
251-
// options to pass into underlying type
252-
max: 1024,
253-
254-
// the parse function
255-
async parse(ctx) {
256-
// the user input or parsed value
257-
ctx.arg;
258-
259-
// the options
260-
ctx.opts.foo;
261-
262-
// "custom name"
263-
ctx.name;
264-
}
265-
}
266-
267-
args: [{ type: "that", name: "custom name", foo: 1 }]
268-
```
269-
270-
**What should I return?**
271-
272-
If the parsing etc was successful, return an object with `parsed` as your value.
273-
274-
If there were any errors etc, return an object with `fail: true` and `message` set to the error message.
275-
276-
```js
277-
// it doesnt have to be a variable btw
278-
return { parsed: myValue };
279-
280-
return {
281-
fail: true,
282-
message: "Your argument failed the vibe check.",
283-
};
284-
```
285-
286-
Usage parsers can easily inherit other parsers using `type`. ArgumentParser automatically parses the lowest type and builds up from there. This means if you have an usage parser with type set to `"number"`, `ctx.arg` will be a number instead of a string.
39+
- [Command Handler](./docs/CommandHandler.md)
40+
- [Commands](./docs/Commands.md)
41+
- [Usages](./docs/Usages.md)
42+
- [Middlewares](./docs/Middlewares.md)
28743

28844
## TODO
28945

46+
- [x] Complete typings
47+
- [x] Middleware
29048
- [ ] Subcommands
291-
- [ ] Permissions
49+
- [ ] Database Middlewares
50+
- [ ] Permissions Middleware
29251

29352
## Changelog
29453

295-
**v.1.0.0:**
54+
**v1.1.0:**
55+
56+
- :warning: **BREAKING:** In `ExecutorContext` (ctx in `failedChecksMessage(ctx)`/now `on("failedChecks", (ctx)=>{})`), the **`checks`** property is now `CommandCheckResult[]` instead of `string[]`. This allows Command Checks to supply additional information about the failed checks, such as
57+
- Codes for custom error messages
58+
- Additional context information (for example, you could supply the user's score or something so your failed checks handler doesnt have to fetch it from a database again, or maybe supply the needed threshold etc)
59+
- :warning: The `invalidUsageMessage` and `failedChecksMessage` functions have been removed. Please use the `invalidUsage` and `failedChecks` events instead.
60+
- Default prefix is now `""` (empty string)
61+
62+
- Added [Middlewares](./docs/Middlewares.md)
63+
- Added `index.d.ts` declarations file that's needlessly complex (and also incomplete)
64+
- Added more documentation
65+
66+
**v1.0.0:**
29667

29768
- Created project
29869
- Added documentation

0 commit comments

Comments
 (0)