@grammyjs/commands 0.3.1 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -19
- package/out/command.d.ts +109 -9
- package/out/command.js +174 -16
- package/out/commands.d.ts +75 -0
- package/out/{plugin.js → commands.js} +64 -9
- package/out/context.d.ts +17 -4
- package/out/context.js +16 -3
- package/out/deps.node.d.ts +0 -1
- package/out/deps.node.js +1 -5
- package/out/errors.d.ts +4 -0
- package/out/errors.js +10 -0
- package/out/jaro-winkler.d.ts +9 -0
- package/out/jaro-winkler.js +109 -0
- package/out/mod.d.ts +2 -1
- package/out/mod.js +1 -1
- package/out/types.d.ts +24 -0
- package/out/types.js +2 -0
- package/package.json +26 -25
- package/out/plugin.d.ts +0 -27
package/README.md
CHANGED
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
## grammY Commands Plugin
|
|
2
2
|
|
|
3
|
-
This plugin provides a convenient way to define and manage commands for your grammY bot. It simplifies the process of
|
|
3
|
+
This plugin provides a convenient way to define and manage commands for your grammY bot. It simplifies the process of
|
|
4
|
+
setting up commands with scopes and localization.
|
|
4
5
|
|
|
5
6
|
## Installation
|
|
6
7
|
|
|
7
|
-
|
|
8
8
|
```sh
|
|
9
9
|
npm i @grammyjs/commands
|
|
10
10
|
```
|
|
11
11
|
|
|
12
12
|
## Usage
|
|
13
13
|
|
|
14
|
-
The main functionality of this plugin is to define your commands, localize them, and give them handlers for each
|
|
15
|
-
|
|
14
|
+
The main functionality of this plugin is to define your commands, localize them, and give them handlers for each
|
|
15
|
+
[scope](https://core.telegram.org/bots/api#botcommandscope), like so:
|
|
16
16
|
|
|
17
17
|
```typescript
|
|
18
18
|
import { Bot } from "grammy";
|
|
@@ -23,9 +23,15 @@ const bot = new Bot("<telegram token>");
|
|
|
23
23
|
const myCommands = new Commands();
|
|
24
24
|
|
|
25
25
|
myCommands.command("start", "Initializes bot configuration")
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
26
|
+
.localize("pt", "start", "Inicializa as configurações do bot")
|
|
27
|
+
.addToScope(
|
|
28
|
+
{ type: "all_private_chats" },
|
|
29
|
+
(ctx) => ctx.reply(`Hello, ${ctx.chat.first_name}!`),
|
|
30
|
+
)
|
|
31
|
+
.addToScope(
|
|
32
|
+
{ type: "all_group_chats" },
|
|
33
|
+
(ctx) => ctx.reply(`Hello, members of ${ctx.chat.title}!`),
|
|
34
|
+
);
|
|
29
35
|
|
|
30
36
|
// Calls `setMyCommands`
|
|
31
37
|
await myCommands.setCommands(bot);
|
|
@@ -36,17 +42,17 @@ bot.use(myCommands);
|
|
|
36
42
|
bot.start();
|
|
37
43
|
```
|
|
38
44
|
|
|
39
|
-
It is very important that you call `bot.use` with your instance of the `Commands` class.
|
|
40
|
-
|
|
45
|
+
It is very important that you call `bot.use` with your instance of the `Commands` class. Otherwise, the command handlers
|
|
46
|
+
will not be registered, and your bot will not respond to those commands.
|
|
41
47
|
|
|
42
48
|
### Context shortcuts
|
|
43
49
|
|
|
44
|
-
This plugin provides a shortcut for setting the commands for the current chat.
|
|
45
|
-
|
|
50
|
+
This plugin provides a shortcut for setting the commands for the current chat. To use it, you need to install the
|
|
51
|
+
commands flavor and the plugin itself, like so:
|
|
46
52
|
|
|
47
53
|
```typescript
|
|
48
54
|
import { Bot, Context } from "grammy";
|
|
49
|
-
import { Commands,
|
|
55
|
+
import { Commands, commands, CommandsFlavor } from "@grammyjs/commands";
|
|
50
56
|
|
|
51
57
|
type BotContext = CommandsFlavor;
|
|
52
58
|
|
|
@@ -54,15 +60,15 @@ const bot = new Bot<BotContext>("<telegram_token>");
|
|
|
54
60
|
bot.use(commands());
|
|
55
61
|
|
|
56
62
|
bot.on("message", async (ctx) => {
|
|
57
|
-
|
|
63
|
+
const cmds = new Commands();
|
|
58
64
|
|
|
59
|
-
|
|
60
|
-
|
|
65
|
+
cmds.command("start", "Initializes bot configuration")
|
|
66
|
+
.localize("pt", "start", "Inicializa as configurações do bot");
|
|
61
67
|
|
|
62
|
-
|
|
68
|
+
await ctx.setMyCommands(cmds);
|
|
63
69
|
|
|
64
|
-
|
|
70
|
+
return ctx.reply("Commands set!");
|
|
65
71
|
});
|
|
66
72
|
|
|
67
|
-
bot.start()
|
|
68
|
-
```
|
|
73
|
+
bot.start();
|
|
74
|
+
```
|
package/out/command.d.ts
CHANGED
|
@@ -1,25 +1,125 @@
|
|
|
1
1
|
import { type BotCommand, type BotCommandScope, type BotCommandScopeAllChatAdministrators, type BotCommandScopeAllGroupChats, type BotCommandScopeAllPrivateChats, type ChatTypeMiddleware, type Context, type Middleware, type MiddlewareObj } from "./deps.node.js";
|
|
2
|
+
import { CommandOptions } from "./types.js";
|
|
2
3
|
export type MaybeArray<T> = T | T[];
|
|
3
4
|
type BotCommandGroupsScope = BotCommandScopeAllGroupChats | BotCommandScopeAllChatAdministrators;
|
|
5
|
+
export declare const matchesPattern: (value: string, pattern: string | RegExp) => boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Class that represents a single command and allows you to configure it.
|
|
8
|
+
*/
|
|
4
9
|
export declare class Command<C extends Context = Context> implements MiddlewareObj<C> {
|
|
5
10
|
private _scopes;
|
|
6
11
|
private _languages;
|
|
7
12
|
private _composer;
|
|
8
|
-
|
|
13
|
+
private _options;
|
|
14
|
+
/**
|
|
15
|
+
* Constructor for the `Command` class.
|
|
16
|
+
* Do not call this directly. Instead, use the `command` method from the `Commands` class
|
|
17
|
+
*
|
|
18
|
+
* @param name Default command name
|
|
19
|
+
* @param description Default command description
|
|
20
|
+
* @param options Options object that shuold apply to this command only
|
|
21
|
+
* @access package
|
|
22
|
+
*/
|
|
23
|
+
constructor(name: string | RegExp, description: string, options?: Partial<CommandOptions>);
|
|
24
|
+
/**
|
|
25
|
+
* Get registered scopes for this command
|
|
26
|
+
*/
|
|
9
27
|
get scopes(): BotCommandScope[];
|
|
28
|
+
/**
|
|
29
|
+
* Get registered languages for this command
|
|
30
|
+
*/
|
|
10
31
|
get languages(): Map<string, {
|
|
11
|
-
name: string;
|
|
32
|
+
name: string | RegExp;
|
|
12
33
|
description: string;
|
|
13
34
|
}>;
|
|
14
|
-
|
|
15
|
-
|
|
35
|
+
/**
|
|
36
|
+
* Get registered names for this command
|
|
37
|
+
*/
|
|
38
|
+
get names(): (string | RegExp)[];
|
|
39
|
+
/**
|
|
40
|
+
* Get the default name for this command
|
|
41
|
+
*/
|
|
42
|
+
get name(): string | RegExp;
|
|
43
|
+
/**
|
|
44
|
+
* Get the default description for this command
|
|
45
|
+
*/
|
|
16
46
|
get description(): string;
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
47
|
+
/**
|
|
48
|
+
* Registers the command to a scope to allow it to be handled and used with `setMyCommands`.
|
|
49
|
+
* This will automatically apply filtering middlewares for you, so the handler only runs on the specified scope.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```ts
|
|
53
|
+
* const myCommands = new Commands();
|
|
54
|
+
* myCommands.command("start", "Initializes bot configuration")
|
|
55
|
+
* .addToScope(
|
|
56
|
+
* { type: "all_private_chats" },
|
|
57
|
+
* (ctx) => ctx.reply(`Hello, ${ctx.chat.first_name}!`),
|
|
58
|
+
* )
|
|
59
|
+
* .addToScope(
|
|
60
|
+
* { type: "all_group_chats" },
|
|
61
|
+
* (ctx) => ctx.reply(`Hello, members of ${ctx.chat.title}!`),
|
|
62
|
+
* );
|
|
63
|
+
* ```
|
|
64
|
+
*
|
|
65
|
+
* @param scope Which scope this command should be available on
|
|
66
|
+
* @param middleware The handler for this command on the specified scope
|
|
67
|
+
* @param options Additional options that should apply only to this scope
|
|
68
|
+
*/
|
|
69
|
+
addToScope(scope: BotCommandGroupsScope, middleware: MaybeArray<ChatTypeMiddleware<C, "group" | "supergroup">>, options?: Partial<CommandOptions>): this;
|
|
70
|
+
addToScope(scope: BotCommandScopeAllPrivateChats, middleware: MaybeArray<ChatTypeMiddleware<C, "private">>, options?: Partial<CommandOptions>): this;
|
|
71
|
+
addToScope(scope: BotCommandScope, middleware: MaybeArray<Middleware<C>>, options?: Partial<CommandOptions>): this;
|
|
72
|
+
/**
|
|
73
|
+
* Creates a matcher for the given command that can be used in filtering operations
|
|
74
|
+
*
|
|
75
|
+
* @example
|
|
76
|
+
* ```ts
|
|
77
|
+
* bot
|
|
78
|
+
* .filter(
|
|
79
|
+
* Command.hasCommand(/\/delete_(.*)/),
|
|
80
|
+
* (ctx) => ctx.reply(`Deleting ${ctx.message?.text?.split("_")[1]}`)
|
|
81
|
+
* )
|
|
82
|
+
* ```
|
|
83
|
+
*
|
|
84
|
+
* @param command Command name or RegEx
|
|
85
|
+
* @param options Options that should apply to the matching algorithm
|
|
86
|
+
* @returns A predicate that matches the given command
|
|
87
|
+
*/
|
|
88
|
+
static hasCommand(command: MaybeArray<string | RegExp>, options: CommandOptions): (ctx: Context) => boolean;
|
|
89
|
+
/**
|
|
90
|
+
* Adds a new translation for the command
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```ts
|
|
94
|
+
* myCommands
|
|
95
|
+
* .command("start", "Starts the bot configuration")
|
|
96
|
+
* .localize("pt", "iniciar", "Inicia a configuração do bot")
|
|
97
|
+
* ```
|
|
98
|
+
*
|
|
99
|
+
* @param languageCode Language this translation applies to
|
|
100
|
+
* @param name Localized command name
|
|
101
|
+
* @param description Localized command description
|
|
102
|
+
*/
|
|
103
|
+
localize(languageCode: string, name: string | RegExp, description: string): this;
|
|
104
|
+
/**
|
|
105
|
+
* Gets the localized command name of an existing translation
|
|
106
|
+
* @param languageCode Language to get the name for
|
|
107
|
+
* @returns Localized command name
|
|
108
|
+
*/
|
|
109
|
+
getLocalizedName(languageCode: string): string | RegExp;
|
|
110
|
+
/**
|
|
111
|
+
* Gets the localized command name of an existing translation
|
|
112
|
+
* @param languageCode Language to get the name for
|
|
113
|
+
* @returns Localized command name
|
|
114
|
+
*/
|
|
22
115
|
getLocalizedDescription(languageCode: string): string;
|
|
116
|
+
/**
|
|
117
|
+
* Converts command to an object representation.
|
|
118
|
+
* Useful for JSON serialization.
|
|
119
|
+
*
|
|
120
|
+
* @param languageCode If specified, uses localized versions of the command name and description
|
|
121
|
+
* @returns Object representation of this command
|
|
122
|
+
*/
|
|
23
123
|
toObject(languageCode?: string): BotCommand;
|
|
24
124
|
middleware(): import("grammy").MiddlewareFn<C>;
|
|
25
125
|
}
|
package/out/command.js
CHANGED
|
@@ -1,58 +1,216 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.Command = void 0;
|
|
3
|
+
exports.Command = exports.matchesPattern = void 0;
|
|
4
4
|
const deps_node_js_1 = require("./deps.node.js");
|
|
5
|
-
const
|
|
5
|
+
const errors_js_1 = require("./errors.js");
|
|
6
|
+
const ensureArray = (value) => Array.isArray(value) ? value : [value];
|
|
7
|
+
const isAdmin = (ctx) => ctx
|
|
8
|
+
.getAuthor()
|
|
9
|
+
.then((author) => ["administrator", "creator"].includes(author.status));
|
|
10
|
+
const matchesPattern = (value, pattern) => typeof pattern === "string" ? value === pattern : pattern.test(value);
|
|
11
|
+
exports.matchesPattern = matchesPattern;
|
|
12
|
+
/**
|
|
13
|
+
* Class that represents a single command and allows you to configure it.
|
|
14
|
+
*/
|
|
6
15
|
class Command {
|
|
7
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Constructor for the `Command` class.
|
|
18
|
+
* Do not call this directly. Instead, use the `command` method from the `Commands` class
|
|
19
|
+
*
|
|
20
|
+
* @param name Default command name
|
|
21
|
+
* @param description Default command description
|
|
22
|
+
* @param options Options object that shuold apply to this command only
|
|
23
|
+
* @access package
|
|
24
|
+
*/
|
|
25
|
+
constructor(name, description, options = {}) {
|
|
8
26
|
this._scopes = [];
|
|
9
27
|
this._languages = new Map();
|
|
10
28
|
this._composer = new deps_node_js_1.Composer();
|
|
11
|
-
this.
|
|
29
|
+
this._options = {
|
|
30
|
+
prefix: "/",
|
|
31
|
+
matchOnlyAtStart: true,
|
|
32
|
+
targetedCommands: "optional",
|
|
33
|
+
};
|
|
34
|
+
this._options = { ...this._options, ...options };
|
|
35
|
+
if (this._options.prefix === "")
|
|
36
|
+
this._options.prefix = "/";
|
|
37
|
+
this._languages.set("default", { name: name, description });
|
|
12
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Get registered scopes for this command
|
|
41
|
+
*/
|
|
13
42
|
get scopes() {
|
|
14
43
|
return this._scopes;
|
|
15
44
|
}
|
|
45
|
+
/**
|
|
46
|
+
* Get registered languages for this command
|
|
47
|
+
*/
|
|
16
48
|
get languages() {
|
|
17
49
|
return this._languages;
|
|
18
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* Get registered names for this command
|
|
53
|
+
*/
|
|
19
54
|
get names() {
|
|
20
55
|
return Array.from(this._languages.values()).map(({ name }) => name);
|
|
21
56
|
}
|
|
57
|
+
/**
|
|
58
|
+
* Get the default name for this command
|
|
59
|
+
*/
|
|
22
60
|
get name() {
|
|
23
61
|
return this._languages.get("default").name;
|
|
24
62
|
}
|
|
63
|
+
/**
|
|
64
|
+
* Get the default description for this command
|
|
65
|
+
*/
|
|
25
66
|
get description() {
|
|
26
67
|
return this._languages.get("default").description;
|
|
27
68
|
}
|
|
28
|
-
addToScope(scope,
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
69
|
+
addToScope(scope, middleware, options = this._options) {
|
|
70
|
+
const middlewareArray = ensureArray(middleware);
|
|
71
|
+
const optionsObject = { ...this._options, ...options };
|
|
72
|
+
switch (scope.type) {
|
|
73
|
+
case "default":
|
|
74
|
+
this._composer
|
|
75
|
+
.filter(Command.hasCommand(this.names, optionsObject))
|
|
76
|
+
.use(...middlewareArray);
|
|
77
|
+
break;
|
|
78
|
+
case "all_chat_administrators":
|
|
79
|
+
this._composer
|
|
80
|
+
.filter(Command.hasCommand(this.names, optionsObject))
|
|
81
|
+
.filter(isAdmin)
|
|
82
|
+
.use(...middlewareArray);
|
|
83
|
+
break;
|
|
84
|
+
case "all_private_chats":
|
|
85
|
+
this._composer
|
|
86
|
+
.filter(Command.hasCommand(this.names, optionsObject))
|
|
87
|
+
.chatType("private")
|
|
88
|
+
.use(...middlewareArray);
|
|
89
|
+
break;
|
|
90
|
+
case "all_group_chats":
|
|
91
|
+
this._composer
|
|
92
|
+
.filter(Command.hasCommand(this.names, optionsObject))
|
|
93
|
+
.chatType(["group", "supergroup"])
|
|
94
|
+
.use(...middlewareArray);
|
|
95
|
+
break;
|
|
96
|
+
case "chat":
|
|
97
|
+
case "chat_administrators":
|
|
98
|
+
if (scope.chat_id) {
|
|
99
|
+
this._composer
|
|
100
|
+
.filter(Command.hasCommand(this.names, optionsObject))
|
|
101
|
+
.filter((ctx) => { var _a; return ((_a = ctx.chat) === null || _a === void 0 ? void 0 : _a.id) === scope.chat_id; })
|
|
102
|
+
.filter(isAdmin)
|
|
103
|
+
.use(...middlewareArray);
|
|
104
|
+
}
|
|
105
|
+
break;
|
|
106
|
+
case "chat_member":
|
|
107
|
+
if (scope.chat_id && scope.user_id) {
|
|
108
|
+
this._composer
|
|
109
|
+
.filter(Command.hasCommand(this.names, optionsObject))
|
|
110
|
+
.filter((ctx) => { var _a; return ((_a = ctx.chat) === null || _a === void 0 ? void 0 : _a.id) === scope.chat_id; })
|
|
111
|
+
.filter((ctx) => { var _a; return ((_a = ctx.from) === null || _a === void 0 ? void 0 : _a.id) === scope.user_id; })
|
|
112
|
+
.use(...middlewareArray);
|
|
113
|
+
}
|
|
114
|
+
break;
|
|
115
|
+
default:
|
|
116
|
+
throw new errors_js_1.InvalidScopeError(scope);
|
|
117
|
+
}
|
|
38
118
|
this._scopes.push(scope);
|
|
39
119
|
return this;
|
|
40
120
|
}
|
|
121
|
+
/**
|
|
122
|
+
* Creates a matcher for the given command that can be used in filtering operations
|
|
123
|
+
*
|
|
124
|
+
* @example
|
|
125
|
+
* ```ts
|
|
126
|
+
* bot
|
|
127
|
+
* .filter(
|
|
128
|
+
* Command.hasCommand(/\/delete_(.*)/),
|
|
129
|
+
* (ctx) => ctx.reply(`Deleting ${ctx.message?.text?.split("_")[1]}`)
|
|
130
|
+
* )
|
|
131
|
+
* ```
|
|
132
|
+
*
|
|
133
|
+
* @param command Command name or RegEx
|
|
134
|
+
* @param options Options that should apply to the matching algorithm
|
|
135
|
+
* @returns A predicate that matches the given command
|
|
136
|
+
*/
|
|
137
|
+
static hasCommand(command, options) {
|
|
138
|
+
const { matchOnlyAtStart, prefix, targetedCommands } = options;
|
|
139
|
+
return (ctx) => {
|
|
140
|
+
if (!ctx.has(":text"))
|
|
141
|
+
return false;
|
|
142
|
+
if (matchOnlyAtStart && !ctx.msg.text.startsWith(prefix)) {
|
|
143
|
+
return false;
|
|
144
|
+
}
|
|
145
|
+
const commandNames = ensureArray(command);
|
|
146
|
+
const commands = prefix === "/"
|
|
147
|
+
? ctx.entities("bot_command")
|
|
148
|
+
: ctx.msg.text.split(prefix).map((text) => ({ text }));
|
|
149
|
+
for (const { text } of commands) {
|
|
150
|
+
const [command, username] = text.split("@");
|
|
151
|
+
if (targetedCommands === "ignored" && username)
|
|
152
|
+
continue;
|
|
153
|
+
if (targetedCommands === "required" && !username)
|
|
154
|
+
continue;
|
|
155
|
+
if (username && username !== ctx.me.username)
|
|
156
|
+
continue;
|
|
157
|
+
if (commandNames.some((name) => (0, exports.matchesPattern)(command.replace(prefix, ""), name))) {
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return false;
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Adds a new translation for the command
|
|
166
|
+
*
|
|
167
|
+
* @example
|
|
168
|
+
* ```ts
|
|
169
|
+
* myCommands
|
|
170
|
+
* .command("start", "Starts the bot configuration")
|
|
171
|
+
* .localize("pt", "iniciar", "Inicia a configuração do bot")
|
|
172
|
+
* ```
|
|
173
|
+
*
|
|
174
|
+
* @param languageCode Language this translation applies to
|
|
175
|
+
* @param name Localized command name
|
|
176
|
+
* @param description Localized command description
|
|
177
|
+
*/
|
|
41
178
|
localize(languageCode, name, description) {
|
|
42
|
-
this._languages.set(languageCode, {
|
|
179
|
+
this._languages.set(languageCode, {
|
|
180
|
+
name: new RegExp(name),
|
|
181
|
+
description,
|
|
182
|
+
});
|
|
43
183
|
return this;
|
|
44
184
|
}
|
|
185
|
+
/**
|
|
186
|
+
* Gets the localized command name of an existing translation
|
|
187
|
+
* @param languageCode Language to get the name for
|
|
188
|
+
* @returns Localized command name
|
|
189
|
+
*/
|
|
45
190
|
getLocalizedName(languageCode) {
|
|
46
191
|
var _a, _b;
|
|
47
192
|
return (_b = (_a = this._languages.get(languageCode)) === null || _a === void 0 ? void 0 : _a.name) !== null && _b !== void 0 ? _b : this.name;
|
|
48
193
|
}
|
|
194
|
+
/**
|
|
195
|
+
* Gets the localized command name of an existing translation
|
|
196
|
+
* @param languageCode Language to get the name for
|
|
197
|
+
* @returns Localized command name
|
|
198
|
+
*/
|
|
49
199
|
getLocalizedDescription(languageCode) {
|
|
50
200
|
var _a, _b;
|
|
51
201
|
return (_b = (_a = this._languages.get(languageCode)) === null || _a === void 0 ? void 0 : _a.description) !== null && _b !== void 0 ? _b : this.description;
|
|
52
202
|
}
|
|
203
|
+
/**
|
|
204
|
+
* Converts command to an object representation.
|
|
205
|
+
* Useful for JSON serialization.
|
|
206
|
+
*
|
|
207
|
+
* @param languageCode If specified, uses localized versions of the command name and description
|
|
208
|
+
* @returns Object representation of this command
|
|
209
|
+
*/
|
|
53
210
|
toObject(languageCode = "default") {
|
|
211
|
+
const localizedName = this.getLocalizedName(languageCode);
|
|
54
212
|
return {
|
|
55
|
-
command:
|
|
213
|
+
command: localizedName instanceof RegExp ? "" : localizedName,
|
|
56
214
|
description: this.getLocalizedDescription(languageCode),
|
|
57
215
|
};
|
|
58
216
|
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { Command } from "./command.js";
|
|
2
|
+
import { Api, BotCommand, BotCommandScope, Context } from "./deps.node.js";
|
|
3
|
+
import { CommandOptions } from "./types.js";
|
|
4
|
+
type SetMyCommandsParams = {
|
|
5
|
+
/**
|
|
6
|
+
* Scope
|
|
7
|
+
*/
|
|
8
|
+
scope?: BotCommandScope;
|
|
9
|
+
language_code?: string;
|
|
10
|
+
commands: BotCommand[];
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Central class that manages all registered commands.
|
|
14
|
+
* This is the starting point for the plugin, and this is what you should pass to `bot.use` so your commands get properly registered.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```typescript
|
|
18
|
+
* const myCommands = new Commands()
|
|
19
|
+
* commands.command("start", "start the bot configuration", (ctx) => ctx.reply("Hello there!"))
|
|
20
|
+
*
|
|
21
|
+
* // Registers the commands with the bot instance.
|
|
22
|
+
* bot.use(myCommands)
|
|
23
|
+
* ```
|
|
24
|
+
*/
|
|
25
|
+
export declare class Commands<C extends Context> {
|
|
26
|
+
private _languages;
|
|
27
|
+
private _scopes;
|
|
28
|
+
private _commands;
|
|
29
|
+
private _composer;
|
|
30
|
+
private _commandOptions;
|
|
31
|
+
constructor(options?: Partial<CommandOptions>);
|
|
32
|
+
private _addCommandToScope;
|
|
33
|
+
private _populateComposer;
|
|
34
|
+
private _populateMetadata;
|
|
35
|
+
/**
|
|
36
|
+
* Registers a new command and returns it.
|
|
37
|
+
* @param name Command name
|
|
38
|
+
* @param description Default command description
|
|
39
|
+
* @param options Extra options that should apply only to this command
|
|
40
|
+
* @returns An instance of the `Command` class
|
|
41
|
+
*/
|
|
42
|
+
command(name: string | RegExp, description: string, options?: Partial<CommandOptions>): Command<C>;
|
|
43
|
+
/**
|
|
44
|
+
* Serializes the commands into multiple objects that can each be passed to a `setMyCommands` call.
|
|
45
|
+
*
|
|
46
|
+
* @returns One item for each combination of command + scope + language
|
|
47
|
+
*/
|
|
48
|
+
toArgs(): SetMyCommandsParams[];
|
|
49
|
+
/**
|
|
50
|
+
* Serializes the commands of a single scope into objects that can each be passed to a `setMyCommands` call.
|
|
51
|
+
*
|
|
52
|
+
* @param scope Selected scope to be serialized
|
|
53
|
+
* @returns One item per command per language
|
|
54
|
+
*/
|
|
55
|
+
toSingleScopeArgs(scope: BotCommandScope): SetMyCommandsParams[];
|
|
56
|
+
/**
|
|
57
|
+
* Registers all commands to be displayed by clients according to their scopes and languages
|
|
58
|
+
* Calls `setMyCommands` for each language of each scope of each command.
|
|
59
|
+
*
|
|
60
|
+
* @param Instance of `bot` or { api: bot.api }
|
|
61
|
+
*/
|
|
62
|
+
setCommands({ api }: {
|
|
63
|
+
api: Api;
|
|
64
|
+
}): Promise<void>;
|
|
65
|
+
/**
|
|
66
|
+
* Alias for {@link toArgs}
|
|
67
|
+
*/
|
|
68
|
+
toJSON(): SetMyCommandsParams[];
|
|
69
|
+
/**
|
|
70
|
+
* @returns A JSON serialized version of all the currently registered commands
|
|
71
|
+
*/
|
|
72
|
+
toString(): string;
|
|
73
|
+
middleware(): import("grammy").MiddlewareFn<C>;
|
|
74
|
+
}
|
|
75
|
+
export {};
|
|
@@ -3,13 +3,27 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.Commands = void 0;
|
|
4
4
|
const command_js_1 = require("./command.js");
|
|
5
5
|
const deps_node_js_1 = require("./deps.node.js");
|
|
6
|
+
/**
|
|
7
|
+
* Central class that manages all registered commands.
|
|
8
|
+
* This is the starting point for the plugin, and this is what you should pass to `bot.use` so your commands get properly registered.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```typescript
|
|
12
|
+
* const myCommands = new Commands()
|
|
13
|
+
* commands.command("start", "start the bot configuration", (ctx) => ctx.reply("Hello there!"))
|
|
14
|
+
*
|
|
15
|
+
* // Registers the commands with the bot instance.
|
|
16
|
+
* bot.use(myCommands)
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
6
19
|
class Commands {
|
|
7
|
-
constructor(
|
|
20
|
+
constructor(options = {}) {
|
|
8
21
|
this._languages = new Set();
|
|
9
22
|
this._scopes = new Map();
|
|
10
23
|
this._commands = [];
|
|
11
24
|
this._composer = new deps_node_js_1.Composer();
|
|
12
|
-
|
|
25
|
+
this._commandOptions = {};
|
|
26
|
+
this._commandOptions = options;
|
|
13
27
|
}
|
|
14
28
|
_addCommandToScope(scope, command) {
|
|
15
29
|
var _a;
|
|
@@ -18,9 +32,7 @@ class Commands {
|
|
|
18
32
|
}
|
|
19
33
|
_populateComposer() {
|
|
20
34
|
for (const command of this._commands) {
|
|
21
|
-
|
|
22
|
-
this._composer.command(args.name, command.middleware());
|
|
23
|
-
}
|
|
35
|
+
this._composer.use(command.middleware());
|
|
24
36
|
}
|
|
25
37
|
}
|
|
26
38
|
_populateMetadata() {
|
|
@@ -35,11 +47,23 @@ class Commands {
|
|
|
35
47
|
}
|
|
36
48
|
});
|
|
37
49
|
}
|
|
38
|
-
|
|
39
|
-
|
|
50
|
+
/**
|
|
51
|
+
* Registers a new command and returns it.
|
|
52
|
+
* @param name Command name
|
|
53
|
+
* @param description Default command description
|
|
54
|
+
* @param options Extra options that should apply only to this command
|
|
55
|
+
* @returns An instance of the `Command` class
|
|
56
|
+
*/
|
|
57
|
+
command(name, description, options = this._commandOptions) {
|
|
58
|
+
const command = new command_js_1.Command(name, description, options);
|
|
40
59
|
this._commands.push(command);
|
|
41
60
|
return command;
|
|
42
61
|
}
|
|
62
|
+
/**
|
|
63
|
+
* Serializes the commands into multiple objects that can each be passed to a `setMyCommands` call.
|
|
64
|
+
*
|
|
65
|
+
* @returns One item for each combination of command + scope + language
|
|
66
|
+
*/
|
|
43
67
|
toArgs() {
|
|
44
68
|
this._populateMetadata();
|
|
45
69
|
const params = [];
|
|
@@ -47,13 +71,22 @@ class Commands {
|
|
|
47
71
|
for (const language of this._languages) {
|
|
48
72
|
params.push({
|
|
49
73
|
scope: JSON.parse(scope),
|
|
50
|
-
language_code: language === "default"
|
|
51
|
-
|
|
74
|
+
language_code: language === "default"
|
|
75
|
+
? undefined
|
|
76
|
+
: language,
|
|
77
|
+
commands: commands.map((command) => command.toObject(language))
|
|
78
|
+
.filter((args) => args.command.length > 0),
|
|
52
79
|
});
|
|
53
80
|
}
|
|
54
81
|
}
|
|
55
82
|
return params.filter((params) => params.commands.length > 0);
|
|
56
83
|
}
|
|
84
|
+
/**
|
|
85
|
+
* Serializes the commands of a single scope into objects that can each be passed to a `setMyCommands` call.
|
|
86
|
+
*
|
|
87
|
+
* @param scope Selected scope to be serialized
|
|
88
|
+
* @returns One item per command per language
|
|
89
|
+
*/
|
|
57
90
|
toSingleScopeArgs(scope) {
|
|
58
91
|
this._populateMetadata();
|
|
59
92
|
const params = [];
|
|
@@ -68,12 +101,24 @@ class Commands {
|
|
|
68
101
|
}
|
|
69
102
|
return params;
|
|
70
103
|
}
|
|
104
|
+
/**
|
|
105
|
+
* Registers all commands to be displayed by clients according to their scopes and languages
|
|
106
|
+
* Calls `setMyCommands` for each language of each scope of each command.
|
|
107
|
+
*
|
|
108
|
+
* @param Instance of `bot` or { api: bot.api }
|
|
109
|
+
*/
|
|
71
110
|
async setCommands({ api }) {
|
|
72
111
|
await Promise.all(this.toArgs().map((args) => api.raw.setMyCommands(args)));
|
|
73
112
|
}
|
|
113
|
+
/**
|
|
114
|
+
* Alias for {@link toArgs}
|
|
115
|
+
*/
|
|
74
116
|
toJSON() {
|
|
75
117
|
return this.toArgs();
|
|
76
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* @returns A JSON serialized version of all the currently registered commands
|
|
121
|
+
*/
|
|
77
122
|
toString() {
|
|
78
123
|
return JSON.stringify(this);
|
|
79
124
|
}
|
|
@@ -81,9 +126,19 @@ class Commands {
|
|
|
81
126
|
this._populateComposer();
|
|
82
127
|
return this._composer.middleware();
|
|
83
128
|
}
|
|
129
|
+
/**
|
|
130
|
+
* Replaces the `toString` method on node.js
|
|
131
|
+
*
|
|
132
|
+
* @see toString
|
|
133
|
+
*/
|
|
84
134
|
[Symbol.for("Deno.customInspect")]() {
|
|
85
135
|
return this.toString();
|
|
86
136
|
}
|
|
137
|
+
/**
|
|
138
|
+
* Replaces the `toString` method on Deno
|
|
139
|
+
*
|
|
140
|
+
* @see toString
|
|
141
|
+
*/
|
|
87
142
|
[Symbol.for("nodejs.util.inspect.custom")]() {
|
|
88
143
|
return this.toString();
|
|
89
144
|
}
|
package/out/context.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { Commands } from "./commands.js";
|
|
1
2
|
import { Context, NextFunction } from "./deps.node.js";
|
|
2
|
-
import {
|
|
3
|
-
export
|
|
3
|
+
import { JaroWinklerOptions } from "./jaro-winkler.js";
|
|
4
|
+
export interface CommandsFlavor<C extends Context = Context> extends Context {
|
|
4
5
|
/**
|
|
5
6
|
* Sets the provided commands for the current chat.
|
|
6
7
|
* Cannot be called on updates that don't have a `chat` property.
|
|
@@ -8,6 +9,18 @@ export type CommandsFlavor<C extends Context = Context> = C & {
|
|
|
8
9
|
* @param commands List of available commands
|
|
9
10
|
* @returns Promise with the result of the operations
|
|
10
11
|
*/
|
|
11
|
-
setMyCommands: (commands: Commands<C>) => Promise<
|
|
12
|
-
|
|
12
|
+
setMyCommands: (commands: Commands<C>) => Promise<void>;
|
|
13
|
+
/**
|
|
14
|
+
* Returns the nearest command to the user input.
|
|
15
|
+
* If no command is found, returns `null`.
|
|
16
|
+
*
|
|
17
|
+
* @param commands List of available commands
|
|
18
|
+
* @param options Options for the Jaro-Winkler algorithm
|
|
19
|
+
* @returns The nearest command or `null`
|
|
20
|
+
*/
|
|
21
|
+
getNearestCommand: (commands: Commands<C>, options?: Partial<JaroWinklerOptions>) => string | null;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Installs the commands flavor into the context.
|
|
25
|
+
*/
|
|
13
26
|
export declare function commands<C extends Context>(): (ctx: CommandsFlavor<C>, next: NextFunction) => Promise<void>;
|
package/out/context.js
CHANGED
|
@@ -1,15 +1,28 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.commands = void 0;
|
|
4
|
+
const jaro_winkler_js_1 = require("./jaro-winkler.js");
|
|
5
|
+
/**
|
|
6
|
+
* Installs the commands flavor into the context.
|
|
7
|
+
*/
|
|
4
8
|
function commands() {
|
|
5
9
|
return (ctx, next) => {
|
|
6
|
-
ctx.setMyCommands = (commands) => {
|
|
7
|
-
if (!ctx.chat)
|
|
10
|
+
ctx.setMyCommands = async (commands) => {
|
|
11
|
+
if (!ctx.chat) {
|
|
8
12
|
throw new Error("cannot call `ctx.setMyCommands` on an update with no `chat` property");
|
|
9
|
-
|
|
13
|
+
}
|
|
14
|
+
await Promise.all(commands
|
|
10
15
|
.toSingleScopeArgs({ type: "chat", chat_id: ctx.chat.id })
|
|
11
16
|
.map((args) => ctx.api.raw.setMyCommands(args)));
|
|
12
17
|
};
|
|
18
|
+
ctx.getNearestCommand = (commands, options) => {
|
|
19
|
+
var _a;
|
|
20
|
+
if ((_a = ctx.msg) === null || _a === void 0 ? void 0 : _a.text) {
|
|
21
|
+
const userInput = ctx.msg.text.substring(1);
|
|
22
|
+
return (0, jaro_winkler_js_1.fuzzyMatch)(userInput, commands, { ...options });
|
|
23
|
+
}
|
|
24
|
+
return null;
|
|
25
|
+
};
|
|
13
26
|
return next();
|
|
14
27
|
};
|
|
15
28
|
}
|
package/out/deps.node.d.ts
CHANGED
|
@@ -1,3 +1,2 @@
|
|
|
1
1
|
export { Api, Bot, type ChatTypeContext, type ChatTypeMiddleware, type CommandMiddleware, Composer, Context, type Middleware, type MiddlewareObj, type NextFunction, } from "grammy";
|
|
2
2
|
export type { BotCommand, BotCommandScope, BotCommandScopeAllChatAdministrators, BotCommandScopeAllGroupChats, BotCommandScopeAllPrivateChats, Chat, } from "grammy/types";
|
|
3
|
-
export { match, P } from "ts-pattern";
|
package/out/deps.node.js
CHANGED
|
@@ -1,12 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
// TODO: Replace with official deno module, once it arrives (https://github.com/gvergnaud/ts-pattern/pull/108)
|
|
3
|
+
exports.Context = exports.Composer = exports.Bot = exports.Api = void 0;
|
|
5
4
|
var grammy_1 = require("grammy");
|
|
6
5
|
Object.defineProperty(exports, "Api", { enumerable: true, get: function () { return grammy_1.Api; } });
|
|
7
6
|
Object.defineProperty(exports, "Bot", { enumerable: true, get: function () { return grammy_1.Bot; } });
|
|
8
7
|
Object.defineProperty(exports, "Composer", { enumerable: true, get: function () { return grammy_1.Composer; } });
|
|
9
8
|
Object.defineProperty(exports, "Context", { enumerable: true, get: function () { return grammy_1.Context; } });
|
|
10
|
-
var ts_pattern_1 = require("ts-pattern");
|
|
11
|
-
Object.defineProperty(exports, "match", { enumerable: true, get: function () { return ts_pattern_1.match; } });
|
|
12
|
-
Object.defineProperty(exports, "P", { enumerable: true, get: function () { return ts_pattern_1.P; } });
|
package/out/errors.d.ts
ADDED
package/out/errors.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.InvalidScopeError = void 0;
|
|
4
|
+
class InvalidScopeError extends Error {
|
|
5
|
+
constructor(scope) {
|
|
6
|
+
super(`Invalid scope: ${scope}`);
|
|
7
|
+
this.name = "InvalidScopeError";
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
exports.InvalidScopeError = InvalidScopeError;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Commands } from "./commands.js";
|
|
2
|
+
import { Context } from "./deps.node.js";
|
|
3
|
+
export declare function distance(s1: string, s2: string): number;
|
|
4
|
+
export type JaroWinklerOptions = {
|
|
5
|
+
ignoreCase?: boolean;
|
|
6
|
+
similarityThreshold?: number;
|
|
7
|
+
};
|
|
8
|
+
export declare function JaroWinklerDistance(s1: string, s2: string, options: Partial<JaroWinklerOptions>): number;
|
|
9
|
+
export declare function fuzzyMatch<C extends Context>(userInput: string, commands: Commands<C>, options: Partial<JaroWinklerOptions>): string | null;
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fuzzyMatch = exports.JaroWinklerDistance = exports.distance = void 0;
|
|
4
|
+
function distance(s1, s2) {
|
|
5
|
+
if (s1.length === 0 || s2.length === 0) {
|
|
6
|
+
return 0;
|
|
7
|
+
}
|
|
8
|
+
const matchWindow = Math.floor(Math.max(s1.length, s2.length) / 2.0) - 1;
|
|
9
|
+
const matches1 = new Array(s1.length);
|
|
10
|
+
const matches2 = new Array(s2.length);
|
|
11
|
+
let m = 0; // number of matches
|
|
12
|
+
let t = 0; // number of transpositions
|
|
13
|
+
let i = 0; // index for string 1
|
|
14
|
+
let k = 0; // index for string 2
|
|
15
|
+
for (i = 0; i < s1.length; i++) {
|
|
16
|
+
// loop to find matched characters
|
|
17
|
+
const start = Math.max(0, i - matchWindow); // use the higher of the window diff
|
|
18
|
+
const end = Math.min(i + matchWindow + 1, s2.length); // use the min of the window and string 2 length
|
|
19
|
+
for (k = start; k < end; k++) {
|
|
20
|
+
// iterate second string index
|
|
21
|
+
if (matches2[k]) {
|
|
22
|
+
// if second string character already matched
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
if (s1[i] !== s2[k]) {
|
|
26
|
+
// characters don't match
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
// assume match if the above 2 checks don't continue
|
|
30
|
+
matches1[i] = true;
|
|
31
|
+
matches2[k] = true;
|
|
32
|
+
m++;
|
|
33
|
+
break;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
// nothing matched
|
|
37
|
+
if (m === 0) {
|
|
38
|
+
return 0.0;
|
|
39
|
+
}
|
|
40
|
+
k = 0; // reset string 2 index
|
|
41
|
+
for (i = 0; i < s1.length; i++) {
|
|
42
|
+
// loop to find transpositions
|
|
43
|
+
if (!matches1[i]) {
|
|
44
|
+
// non-matching character
|
|
45
|
+
continue;
|
|
46
|
+
}
|
|
47
|
+
while (!matches2[k]) {
|
|
48
|
+
// move k index to the next match
|
|
49
|
+
k++;
|
|
50
|
+
}
|
|
51
|
+
if (s1[i] !== s2[k]) {
|
|
52
|
+
// if the characters don't match, increase transposition
|
|
53
|
+
// HtD: t is always less than the number of matches m, because transpositions are a subset of matches
|
|
54
|
+
t++;
|
|
55
|
+
}
|
|
56
|
+
k++; // iterate k index normally
|
|
57
|
+
}
|
|
58
|
+
// transpositions divided by 2
|
|
59
|
+
t /= 2.0;
|
|
60
|
+
return (m / s1.length + m / s2.length + (m - t) / m) / 3.0; // HtD: therefore, m - t > 0, and m - t < m
|
|
61
|
+
// HtD: => return value is between 0 and 1
|
|
62
|
+
}
|
|
63
|
+
exports.distance = distance;
|
|
64
|
+
// Computes the Winkler distance between two string -- intrepreted from:
|
|
65
|
+
// http://en.wikipedia.org/wiki/Jaro%E2%80%93Winkler_distance
|
|
66
|
+
// s1 is the first string to compare
|
|
67
|
+
// s2 is the second string to compare
|
|
68
|
+
// dj is the Jaro Distance (if you've already computed it), leave blank and the method handles it
|
|
69
|
+
// ignoreCase: if true strings are first converted to lower case before comparison
|
|
70
|
+
function JaroWinklerDistance(s1, s2, options) {
|
|
71
|
+
if (s1 === s2) {
|
|
72
|
+
return 1;
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
if (options.ignoreCase) {
|
|
76
|
+
s1 = s1.toLowerCase();
|
|
77
|
+
s2 = s2.toLowerCase();
|
|
78
|
+
}
|
|
79
|
+
const jaro = distance(s1, s2);
|
|
80
|
+
const p = 0.1; // default scaling factor
|
|
81
|
+
let l = 0; // length of the matching prefix
|
|
82
|
+
while (s1[l] === s2[l] && l < 4) {
|
|
83
|
+
l++;
|
|
84
|
+
}
|
|
85
|
+
// HtD: 1 - jaro >= 0
|
|
86
|
+
return jaro + l * p * (1 - jaro);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
exports.JaroWinklerDistance = JaroWinklerDistance;
|
|
90
|
+
function fuzzyMatch(userInput, commands, options) {
|
|
91
|
+
const defaultSimilarityThreshold = 0.85;
|
|
92
|
+
const similarityThreshold = options.similarityThreshold ||
|
|
93
|
+
defaultSimilarityThreshold;
|
|
94
|
+
const commandsSet = new Set(commands
|
|
95
|
+
.toJSON()
|
|
96
|
+
.flatMap((item) => item.commands.map((command) => command.command)));
|
|
97
|
+
const bestMatch = Array.from(commandsSet).reduce((best, command) => {
|
|
98
|
+
const similarity = JaroWinklerDistance(userInput, command, {
|
|
99
|
+
...options,
|
|
100
|
+
});
|
|
101
|
+
return similarity > best.similarity
|
|
102
|
+
? { command, similarity }
|
|
103
|
+
: best;
|
|
104
|
+
}, { command: null, similarity: 0 });
|
|
105
|
+
return bestMatch.similarity > similarityThreshold
|
|
106
|
+
? bestMatch.command
|
|
107
|
+
: null;
|
|
108
|
+
}
|
|
109
|
+
exports.fuzzyMatch = fuzzyMatch;
|
package/out/mod.d.ts
CHANGED
package/out/mod.js
CHANGED
|
@@ -14,5 +14,5 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
14
14
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./commands.js"), exports);
|
|
17
18
|
__exportStar(require("./context.js"), exports);
|
|
18
|
-
__exportStar(require("./plugin.js"), exports);
|
package/out/types.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Supported command options
|
|
3
|
+
*/
|
|
4
|
+
export interface CommandOptions {
|
|
5
|
+
/**
|
|
6
|
+
* The prefix used to identify a command.
|
|
7
|
+
* Defaults to `/`.
|
|
8
|
+
*/
|
|
9
|
+
prefix: string;
|
|
10
|
+
/**
|
|
11
|
+
* Whether the command should only be matched at the start of the message.
|
|
12
|
+
* Defaults to `true`.
|
|
13
|
+
*/
|
|
14
|
+
matchOnlyAtStart: boolean;
|
|
15
|
+
/**
|
|
16
|
+
* Whether to ignore or only care about commands ending with the bot's username.
|
|
17
|
+
* Defaults to `"optional"`.
|
|
18
|
+
*
|
|
19
|
+
* - `"ignored"`: only non-targeted commands are matched
|
|
20
|
+
* - `"optional"`: both targeted and non-targeted commands are matched
|
|
21
|
+
* - `"required"`: only targeted commands are matched
|
|
22
|
+
*/
|
|
23
|
+
targetedCommands: "ignored" | "optional" | "required";
|
|
24
|
+
}
|
package/out/types.js
ADDED
package/package.json
CHANGED
|
@@ -1,27 +1,28 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
"
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
"
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
"
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
"
|
|
26
|
-
|
|
2
|
+
"name": "@grammyjs/commands",
|
|
3
|
+
"version": "0.5.1",
|
|
4
|
+
"description": "grammY Commands Plugin",
|
|
5
|
+
"main": "out/mod.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"backport": "deno task backport",
|
|
8
|
+
"prepare": "deno task backport"
|
|
9
|
+
},
|
|
10
|
+
"keywords": [
|
|
11
|
+
"grammY",
|
|
12
|
+
"telegram",
|
|
13
|
+
"bot",
|
|
14
|
+
"commands"
|
|
15
|
+
],
|
|
16
|
+
"author": "Roz <roz@rjmunhoz.me>",
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"grammy": "^1.17.1",
|
|
20
|
+
"ts-pattern": "^5.0.1"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"typescript": "^5.1.6"
|
|
24
|
+
},
|
|
25
|
+
"files": [
|
|
26
|
+
"out"
|
|
27
|
+
]
|
|
27
28
|
}
|
package/out/plugin.d.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { Command } from "./command.js";
|
|
2
|
-
import { Api, BotCommand, BotCommandScope, Context } from "./deps.node.js";
|
|
3
|
-
type SetMyCommandsParams = {
|
|
4
|
-
scope?: BotCommandScope;
|
|
5
|
-
language_code?: string;
|
|
6
|
-
commands: BotCommand[];
|
|
7
|
-
};
|
|
8
|
-
export declare class Commands<C extends Context> {
|
|
9
|
-
private _languages;
|
|
10
|
-
private _scopes;
|
|
11
|
-
private _commands;
|
|
12
|
-
private _composer;
|
|
13
|
-
constructor(commands?: Command<C>[]);
|
|
14
|
-
private _addCommandToScope;
|
|
15
|
-
private _populateComposer;
|
|
16
|
-
private _populateMetadata;
|
|
17
|
-
command(name: string, description: string): Command<C>;
|
|
18
|
-
toArgs(): SetMyCommandsParams[];
|
|
19
|
-
toSingleScopeArgs(scope: BotCommandScope): SetMyCommandsParams[];
|
|
20
|
-
setCommands({ api }: {
|
|
21
|
-
api: Api;
|
|
22
|
-
}): Promise<void>;
|
|
23
|
-
toJSON(): SetMyCommandsParams[];
|
|
24
|
-
toString(): string;
|
|
25
|
-
middleware(): import("grammy").MiddlewareFn<C>;
|
|
26
|
-
}
|
|
27
|
-
export {};
|